Skip to content Skip to sidebar Skip to footer

Common Lisp: Launch Subprocess With Different Working Directory Than Lisp Process

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 current w

Solution 1:

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.

Solution 2:

I ended up writing krzysz00's suggestion up into a package that can be found here.

Then someone pointed out that UIOP comes with getcwd and chdir. If you have a fairly recent lisp, UIOP should come included with your edition of asdf.

Solution 3:

I dont know what lisp is but could this work?

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

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

Post a Comment for "Common Lisp: Launch Subprocess With Different Working Directory Than Lisp Process"