假设我有一个目录 A 和子目录 B。我 cd 进入 A 并启动 lisp。在该 lisp 进程中,我想启动一个 Python 子进程,其中 Python 将 B 视为其当前工作目录。 lisp 进程需要在 A 中拥有 cwd,而 python 进程应该在 B 中拥有 cwd。我如何以跨平台、简单的方式做到这一点?
我正在寻找一种与 CCL 和 SBCL 一起使用的解决方案(可能使用“运行程序函数”),并且适用于 Windows、Linux 和 OS X。
我查看了 CCL 运行程序文档,没有找到更改启动进程的 cwd 的方法。
我查看了 Python 命令行参数,没有看到会更改 python 进程的 cwd 的参数。
我想到了运行程序调用“cd B;” python ...',但我不确定它是如何工作的,因为它实际上运行两个程序; cd,然后是 python。
Python 代码作为输入(作为文件)提供,因此我无法更改任何代码(通过添加 os.chdir() 调用或类似的调用)。
将 python 输入文件作为子进程启动的 python 包装文件并不理想,因为我正在发送 stdin 并监听由 lisp 启动的 python 进程的 stdout。在 lisp 和 python 进程之间添加另一个子进程来评估输入文件意味着我需要进行大量的 stout/stdin 中继,而且我感觉这会很脆弱。
krzysz00 的方法非常有效。由于目录更改是在 lisp 中处理的,因此在启动 python 进程之前,这种方法适用于在不同子目录(不仅仅是 python)中启动其他进程。
对于文档,这里是我的代码,使用适用于 SBCL 和 CCL 的 krzsz00 方法。请注意,它使用 Hoyte 的 defmacro!宏,从让拉姆达,轻松避免不需要的变量捕获:
#+: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))))
Usage:
(with-cwd "./B"
(run-program ...))