Can I specify directory for shell command?
-
02-07-2021 - |
题
I use the following function to run shell commands:
(defun sh (cmd)
#+clisp (shell cmd)
#+ecl (si:system cmd)
#+sbcl (sb-ext:run-program "/bin/sh" (list "-c" cmd) :input nil :output*standard-output*)
#+clozure (ccl:run-program "/bin/sh" (list "-c" cmd) :input nil :output*standard-output*)))
For example, How to specify the current directory for command python -m CGIHTTPServer
?
Sincerely!
解决方案
In ECL you can use EXT:CHDIR before SYSTEM, which changes both default-pathname-defaults and the value of the current directory, as understood by the operating system and C library.
BTW: If possible use (EXT:RUN-PROGRAM "command" list-of-args) instead
其他提示
A more portable way would be to use pathnames and dynamically binding *default-pathname-defaults*
, which would effectively set your current working directory. I had the same problem today. Here is a working adaptation of dot->png
from Land of Lisp text by Conrad Barski, that specifies the current working directory:
(defun dot->png (filespec thunk)
"Save DOT information generated by a thunk on a *STANDARD-OUTPUT* to a FILESPEC file. Then use FILESPEC to create a corresponding png picture of a graph."
;; dump DOT file first
(let ((*default-pathname-defaults*
(make-pathname :directory (pathname-directory (pathname filespec)))))
;; (format t "pwd (curr working dir): ~A~%" *default-pathname-defaults*)
(with-open-file (*standard-output*
filespec
:direction :output
:if-exists :supersede)
(funcall thunk))
#+sbcl
(sb-ext:run-program "/bin/sh"
(list "-c" (concatenate 'string "dot -Tpng -O " filespec))
:input nil
:output *standard-output*)
#+clozure
(ccl:run-program "/bin/sh"
(list "-c" (concatenate 'string "dot -Tpng -O" filespec))
:input nil
:output *standard-output*)))
Posted in the hope that this could be useful to someone in a similar situation & running across this thread.