公共Lisp:使用与Lisp进程不同的工作目录启动子进程

2024-05-16 08:19:06 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一个目录a,子目录B.iccd到a并启动lisp。我将Python的当前运行目录视为Python的当前运行目录。lisp进程需要在A中有cwd,python进程应该在B中有cwd?在

我正在寻找一个能与CCL和SBCL一起工作的解决方案(可能使用“run program function”),适用于Windows、Linux和osx

我查看了CCL运行程序的文档,但是我没有找到一种方法来更改已启动进程的cwd。在

我查看了Python命令行参数,但没有看到会改变Python进程的cwd的参数。在

我曾考虑过对“cd B;python…”的运行程序调用,但我不确定这将如何工作,因为它实际上正在运行两个程序:cd,然后是python。在

Python代码作为输入(作为文件)提供,因此我无法更改任何代码(通过添加os.chdir公司()呼叫或类似的)。在

作为子进程启动python输入文件的python包装文件并不理想,因为我发送stdin并监听lisp启动的python进程的stdout。在lisp和python进程之间添加另一个子进程来计算输入文件,这意味着我需要做大量的strut/stdin中继,我觉得这很脆弱。在

krzysz00的方法非常有效。由于目录更改是在lisp中处理的,所以在python进程启动之前,这种方法可以在不同的子目录中启动其他进程(而不仅仅是python)。在

对于文档,下面是我使用krzzz00方法的代码,该方法适用于SBCL&CCL。注意它使用了Hoyte的demacro!宏,来自Let Over Lambda,以轻松避免不需要的变量捕获:

#+:SBCL
(defun cwd (dir)
  (sb-posix:chdir dir))

(defun getcwd ()
  #+SBCL (sb-unix:posix-getcwd)
  #+CCL (current-directory))

(defmacro! with-cwd (dir &body body)
  `(let ((,g!cwd (getcwd)))
     (unwind-protect (progn
                       (cwd ,dir)
                       ,@body)
     (cwd ,g!cwd))))

用法:

^{pr2}$

Tags: 文件方法代码文档程序目录参数进程
3条回答

我不知道lisp是什么,但这行得通吗?在

  import subprocess
  subprocess.Popen('python myscript.py', cwd='B')

http://docs.python.org/library/subprocess.html

最后我把krzysz00的建议写进了一个可以找到here的包中。在

然后有人指出UIOP与{}和{}一起出现。如果您有一个相当新的lisp,UIOP应该包含在您的^{}版本中。在

要运行外部程序(如可移植的python进程),请参见external-program。要更改当前的工作目录,请使用下面复制的文件http://files.b9.com/lboot/utils.lisp中稍加修改的(公共域)函数cwd。在

(defun cwd (&optional dir)
  "Change directory and set default pathname"
  (cond
   ((not (null dir))
    (when (and (typep dir 'logical-pathname)
           (translate-logical-pathname dir))
      (setq dir (translate-logical-pathname dir)))
    (when (stringp dir)
      (setq dir (parse-namestring dir)))
    #+allegro (excl:chdir dir)
    #+clisp (#+lisp=cl ext:cd #-lisp=cl lisp:cd dir)
    #+(or cmu scl) (setf (ext:default-directory) dir)
    #+cormanlisp (ccl:set-current-directory dir)
    #+(and mcl (not openmcl)) (ccl:set-mac-default-directory dir)
    #+openmcl (ccl:cwd dir)
    #+gcl (si:chdir dir)
    #+lispworks (hcl:change-directory dir)
    #+sbcl (sb-posix:chdir dir)
    (setq cl:*default-pathname-defaults* dir))
   (t
    (let ((dir
       #+allegro (excl:current-directory)
       #+clisp (#+lisp=cl ext:default-directory #-lisp=cl lisp:default-directory)
       #+(or cmu scl) (ext:default-directory)
       #+sbcl (sb-unix:posix-getcwd/)
       #+cormanlisp (ccl:get-current-directory)
       #+lispworks (hcl:get-working-directory)
       #+mcl (ccl:mac-default-directory)
       #-(or allegro clisp cmu scl cormanlisp mcl sbcl lispworks) (truename ".")))
      (when (stringp dir)
    (setq dir (parse-namestring dir)))
      dir))))

结合这两个函数,您需要的代码是:

^{pr2}$

这将cd到B,以python file.py &的方式运行python进程,将python进程的stdin/stdout发送到指定的流(有关详细信息,请参阅external-program文档),最后执行另一个将lisp进程返回给A的cwd。如果lisp进程应该等到python进程完成时再执行,使用external-program:run代替external-program:start。在

相关问题 更多 >