Common Lisp: Launch subprocess with different working directory than lisp process

前端 未结 3 1168
面向向阳花
面向向阳花 2021-01-14 02:08

Suppose I have a directory A, and subdirectory B. I cd into A and launch lisp. In that lisp process, I would like to launch a Python subprocess where Python sees B as its cu

3条回答
  •  抹茶落季
    2021-01-14 02:43

    To run external programs (like your python process portably) see external-program. To change the current working directory, use this slightly modified (public domain) function cwd from the file http://files.b9.com/lboot/utils.lisp, which is reproduced below.

    (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))))
    

    Combining these two functions, the code you want is:

    (cwd #p"../b/")
    (external-program:start "python" '("file.py") :output *pythins-stdout-stream* :input *pythons-stdin-stream*)
    (cwd #p"../a/")
    

    This will cd to B, run the python process as if by python file.py &, send the python process's stdin/stdout to the specified streams (look at the external-program documentation for more details), and finally execute another cwd that returns the lisp process to A. If the lisp process should wait until the python process is finished, use external-program:run instead of external-program:start.

提交回复
热议问题