我在使用Ubuntu 14.04并在命令行上执行diff
时遇到问题。请查看以下Go代码:
package main
import "fmt"
import "log"
import "os/exec"
func main() {
output, err := exec.Command("diff", "-u", "/tmp/revision-1", "/tmp/revision-4").Output()
if err != nil {
log.Fatalln(err)
}
fmt.Println(string(output))
}
如果我使用go run test.go
执行此操作,则会收到以下错误:
2015/03/18 14:39:25 exit status 1
exit status 1
diff
出现了问题,它返回1
作为退出代码。只有diff
命令似乎会抛出错误。如果我使用cat
或wc
命令,代码运行正常。
为什么diff
在这里不起作用而其他命令有效?
答案 0 :(得分:5)
使用exec
运行程序时,如果退出代码不是0,则会出错。来自doc:
如果命令运行,返回的错误为nil,复制stdin,stdout和stderr没有问题,退出时退出状态为零。
如果命令无法运行或未成功完成,则错误类型为* ExitError。对于I / O问题,可能会返回其他错误类型。
所以这里发生的是当文件不同时diff会返回错误,但你会把它当成运行时错误。只需更改您的代码即可反映出它不是。可以通过检查错误来实现。
e.g。像这样的东西:
output, err := exec.Command("diff", "-u", "/tmp/revision-1", "/tmp/revision-4").CombinedOutput()
if err != nil {
switch err.(type) {
case *exec.ExitError:
// this is just an exit code error, no worries
// do nothing
default: //couldnt run diff
log.Fatal(err)
}
}
另外,我已将其更改为CombinedOutput
,因此如果发生任何差异特定错误,您也会看到stderr。
注意即使其中一个文件不存在,您也会收到“有效”错误。因此,您可以通过执行以下操作来检查ExitError
的退出代码:
switch e := err.(type) {
case *exec.ExitError:
// we can check the actual error code. This is not platform portable
if status, ok := e.Sys().(syscall.WaitStatus); ok {
// exit code 1 means theres a difference and is not an error
if status.ExitStatus() != 1 {
log.Fatal(err)
}
}