【问题标题】:Can I specify directory for shell command?我可以为 shell 命令指定目录吗?
【发布时间】:2012-09-17 08:49:43
【问题描述】:

我使用以下函数来运行 shell 命令:

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

例如,如何为命令python -m CGIHTTPServer指定当前目录?

真诚的!

【问题讨论】:

  • 一种方法是在执行之前 cd 到目录,因为脚本将在您的当前目录中运行。
  • (probe-file #P"./") 怎么样?
  • (probe-file #P"./") 将返回我在执行 shell 命令时要更改的当前目录。现在我使用一个脚本来包装 shell 命令,然后我运行脚本,我可以在其中 cd 到任何指定的目录。
  • @wvxvw 你是对的。我需要在调用 sh 函数之前连接命令。谢谢!

标签: common-lisp sbcl ccl ecl


【解决方案1】:

在 ECL 中,您可以在 SYSTEM 之前使用 EXT:CHDIR,这会更改 default-pathname-defaults 和当前目录的值,如操作系统和 C 库所理解的那样。

顺便说一句:如果可能,请改用 (EXT:RUN-PROGRAM "command" list-of-args)

【讨论】:

    【解决方案2】:

    一种更便携的方法是使用路径名并动态绑定*default-pathname-defaults*,这将有效地设置您当前的工作目录。我今天遇到了同样的问题。这是 Conrad Barski 对 Land of Lisp 文本中dot->png 的工作改编,它指定了当前工作目录:

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

    发布希望这对处于类似情况并在此线程中运行的人有用。

    【讨论】: