如果出错,如何获得系统命令的输出?

时间:2017-02-10 10:27:31

标签: racket

在关于这种事情的previous question中,我学会了如何在成功的情况下访问命令的输出,并在出现错误时执行其他代码。但是,通常在发生错误时打印命令输出对我来说更有意义。解决另一个问题的代码是:

(with-output-to-string
  (lambda ()
    (unless (system "ls -la")
      ;; handle error here
      )))

如何在unless表单中获取系统命令的输出?

用法示例:我想运行一些系统命令,只想打印"成功!"到终端,如果命令成功,如果出错,我想打印"错误!"加上命令的实际输出。

注意:我不想两次运行命令,因为许多系统命令都有副作用,我不想触发两次,只是为了获得输出,这样的第二次调用的输出可能与无论如何首先打电话,因此可能无法反映实际错误。

1 个答案:

答案 0 :(得分:2)

过程process生成一个包含五个值的列表,其中两个是输入端口(从子进程的标准输出和stderr管道输出),最后一个是可用于获取的过程子进程的退出代码。例如,

> (process "someCommand")
'(#<input-port:subprocess-stdout>
  #<output-port:subprocess-stdin>
  11292
  #<input-port:subprocess-stderr>
  #<procedure:control>)

要获取子进程的退出代码,请使用参数'exit-code调用最后一项(这是一个过程),如下所示:

((last (process "someCommand")) 'exit-code)

但请注意,如果子进程仍在运行,则上述过程将返回#f而不是整数,因此首先使用参数'wait调用它,然后使用'exit-code调用它。例如,

> (define cmd (process "someCommand"))
> ((last cmd) 'wait)
> ((last cmd) 'exit-code)   ; should now return an integer

现在可以比较退出代码,并且在非零的情况下,可以读取和打印stderr输入端口。

下面是一个示例函数,如果子进程成功执行,则生成"Success!",并在出现错误时打印"Error! + error-message"

(define (output command)
  (define cmd (process command))
  ((last cmd) 'wait)
  (define exit-code ((last cmd) 'exit-code))
  (if (= exit-code 0)
      "Success!"
      (printf "Error!\n~a\n" (read-line (fourth cmd)))))

例如;

> (output "date")
Success!
> (output "ls -al")
Success!
> (output "someCommand")
Error!
/bin/sh: 1: someCommand: not found