Go执行shell指令的最佳方式及execute command failed:exit status 1解决方法

1,542 阅读2分钟

“携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第13天,点击查看活动详情

1.前言

通过Go执行shell命令在网上有很多方式,但是在调试的时候往往发现这些方式存在或多或少的问题,最终在这里找到一些目前感觉最佳的方式,出错后的提示信息足够完整。

2.代码示例

这里以修改ip的命令为例:

package main

import (
	"fmt"
	"os/exec"
)

func main() {
	cmd := exec.Command("ifconfig", "ens33", "40.40.40.155",
		"netmask", "255.255.255.0")
	output, err := cmd.CombinedOutput()
	if err != nil {
		fmt.Println(fmt.Sprint(err) + ": " + string(output))
	}
	fmt.Println(string(output))
}

当编译后直接运行时报错:

exit status 255: SIOCSIFADDR: 不允许的操作
SIOCSIFFLAGS: 不允许的操作
SIOCSIFNETMASK: 不允许的操作

SIOCSIFADDR: 不允许的操作
SIOCSIFFLAGS: 不允许的操作
SIOCSIFNETMASK: 不允许的操作

这样我们就可以大致猜测出来是运行权限的问题,然后使用root权限运行程序即可解决,使用一些其它的方式给到的错误都是什么exit 1或者exit 255之类的状态值,不方便调试。

3. execute command failed:exit status 1

如果你在使用一些其它方式调用shell时发现:

execute command failed:exit status 1

参考这里也给出了另一种写法:

stackoverflow.com/questions/1…

4. 代码

cmd := exec.Command("find", "/", "-maxdepth", "1", "-exec", "wc", "-c", "{}", "\\")
var out bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
    fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
    return
}
fmt.Println("Result: " + out.String())

5. 区别

从名字就可以大致猜出来,run、CombinedOutput分别是命令执行后的运行以及组合的结果,所以CombinedOutput会将错误信息和执行结果组合起来,所以如果报错的话通过CombinedOutput可以打印出错误信息,而运行run的话则需要单独捕获错误信息进行打印(还有一个cmd.Output,感兴趣的可以试一下)。