为了账号安全,请及时绑定邮箱和手机立即绑定

当退出代码不为零时,Golang exec.Command 返回 nil 错误

当退出代码不为零时,Golang exec.Command 返回 nil 错误

Go
翻过高山走不出你 2023-07-04 15:05:50
我正在尝试在 Golang 中运行命令,但看起来它丢失了退出代码,因为错误为零:func runCommand() []byte, error {  cmd := exec.Command("/bin/bash", "-c", "KUBECONFIG=/tmp/.kube/config helm version")  cmd.Stdin = os.Stdin  cmd.Stderr = os.Stderr  stdOut, err := cmd.StdoutPipe()  if err != nil {      return nil, err  }  if err := cmd.Start(); err != nil {      return nil, err  }  bytes, err := ioutil.ReadAll(stdOut)  if err != nil {      return nil, err  }  if err := cmd.Wait(); err != nil {      return nil, err  }  fmt.Println(string(bytes))  return bytes, nil}即使命令返回退出代码 != 0,也会返回 nil。如果我输入:$> /bin/bash -c KUBECONFIG=/tmp/.kube/config helm version$<$> echo $?$< 0如果我输入:$> /bin/bash -c 'KUBECONFIG=/tmp/.kube/config helm version'$< ...connection refused$> echo $?$< 1所以我尝试将命令用单引号括起来:cmd := exec.Command("/bin/bash", "-c", "'KUBECONFIG=/tmp/.kube/config helm version'")但后来我得到:/bin/bash: KUBECONFIG=/tmp/.kube/config helm version: No such file or directory(不用说 /tmp/.kube/config 就在那里,但我不认为 no such 文件或目录指的是它)。我究竟做错了什么?谢谢更新:事实证明我错了。事实上,我尝试了两个命令,出于某种原因,我确信失败的是我上面提到的那个,而第二个命令正在退出,状态代码不同于 0。代码按预期工作,错误不为零如果退出代码!= 0。对此表示抱歉。
查看完整描述

1 回答

?
GCT1015

TA贡献1827条经验 获得超4个赞

看来你应该能够通过exec.ExitError, see exec package获得它。请注意,您可能需要 Go 1.12。这是一个可运行的示例(但它不会在 go Playground 上为您提供实际的输出):

package main


import (

    "fmt"

    "io/ioutil"

    "os"

    "os/exec"

)


func main() {

    cmd := exec.Command(`/bin/bash`, `-c`, `FOO=bar ls /foo`)

    cmd.Stdin = os.Stdin

    cmd.Stderr = os.Stderr

    stdOut, err := cmd.StdoutPipe()

    if err != nil {

        fmt.Println("Error 1")

    }

    if err := cmd.Start(); err != nil {

        fmt.Println("Error 2")

    }

    bytes, err := ioutil.ReadAll(stdOut)

    if err != nil {

        fmt.Println("Error 3")

    }

    if err := cmd.Wait(); err != nil {

        fmt.Println("Error 4")

        if exitError, ok := err.(*exec.ExitError); ok {

            fmt.Printf("Exit code is %d\n", exitError.ExitCode())

        }

    }

    fmt.Println(string(bytes))

}

在我的系统上打印:


$ go run main.go

ls: cannot access '/foo': No such file or directory

Error 4

Exit code is 2

如果这对您不起作用,也许值得遵循 @JimB 的建议并直接调用 helm ?Go 标准库也应该支持管道:


它包装了 os.StartProcess 以便更轻松地重新映射 stdin 和 stdout、使用管道连接 I/O 以及进行其他调整。



查看完整回答
反对 回复 2023-07-04
  • 1 回答
  • 0 关注
  • 132 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信