在elisp中查找shell命令的退出代码

12

我使用shell-command-to-string从shell调用了一个命令。然而,我不仅要获取它的输出,还要获取命令的退出码。

我该如何实现?


这看起来很困难;我能看到唯一能做到这一点的命令是call-process,需要对一个临时缓冲区进行一些处理...类似这样(setq ret-val (call-process "ls -l" nil "mytempbuf" nil)) - abiessu
1个回答

22

shell-command-to-string只是一个基于更基本的进程函数的方便包装器。

对于简单同步进程,可以使用 call-process 函数。call process 将返回进程的退出代码,你可以将所有输出重定向到缓冲区,在缓冲区上使用buffer-string获取文本。

这里是一个例子:

;; this single expression returns a list of two elements, the process 
;; exit code, and the process output
(with-temp-buffer 
  (list (call-process "ls" nil (current-buffer) nil "-h" "-l")
        (buffer-string)))


;; we could wrap it up nicely:
(defun process-exit-code-and-output (program &rest args)
  "Run PROGRAM with ARGS and return the exit code and output in a list."
  (with-temp-buffer 
    (list (apply 'call-process program nil (current-buffer) nil args)
          (buffer-string))))

(process-exit-code-and-output "ls" "-h" "-l" "-a") ;; => (0 "-r-w-r-- 1 ...")

另外需要注意的是:如果您想要使用进程进行更多复杂的操作,应阅读有关start-process的文档,以及如何使用sentinels和filters,这是一个非常强大的API。


1
嗯...为什么在第二个版本中使用apply?只是好奇。 - Diego Sevilla
2
call-process传递的参数是可变的,这意味着我不能仅仅将process-exit-code-and-output中的参数传递给call-process,因为它需要许多参数,而不是参数列表。apply是一个很好的函数,因为它也使用可变参数,但它有一个特殊的行为。如果apply的最后一个参数是一个列表,则其中的元素会被视为单独给出的参数。这是为了方便处理使用可变参数的情况。例如:(apply '+ 1 2 3 (4 5)) == (apply '+ 1 2 3 4 5) - Jordon Biondo
啊,我明白了。我没记住那个调用是可变参数的。谢谢! - Diego Sevilla

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接