Golang中无法运行Ubuntu命令的解决方法

Golang中无法运行Ubuntu命令的解决方法 大家好,

出于某些原因,我无法运行这段代码:

fmt.Println("\nChecking if protected-mode is on each .conf file...")
protectedModeStatusByte, _ := exec.Command("sudo", "grep", "^protected-mode", "/etc/redis/*.conf", "|", "wc", "-l").Output()
protectedModeStatus := string(protectedModeStatusByte[:])
fmt.Println(protectedModeStatus)
fmt.Printf("\nprotected-mode Status: %s", protectedModeStatus)

输出是空的:

Checking if protected-mode is on each .conf files...


protected-mode Status: 

有趣的是,在同一个 .go 文件中,我有一段针对另一个 Linux 命令的类似代码,它运行得非常好!这完全说不通!

谢谢!


更多关于Golang中无法运行Ubuntu命令的解决方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

6 回复

这个 Linux 命令是否也能将一个命令的输出通过管道传递给另一个命令?

更多关于Golang中无法运行Ubuntu命令的解决方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我的天啊!我发誓我之前试过那个方法!;-( 第一个解决方案返回了0。但第二个方案有效!今天真不是个适合编码的日子……

非常感谢你的帮助!

output, _ := exec.Command("sh", "-c", "sudo grep ^protected-mode /etc/redis/*.conf | wc -l").Output()
fmt.Println(string(output))
wc := exec.Command("wc", "-l")
grep := exec.Command("sudo", "grep", "^protected-mode", "/etc/redis/*.conf")

pipe, _ := grep.StdoutPipe()
defer pipe.Close()

wc.Stdin = pipe
grep.Start()

res, _ := wc.Output()
fmt.Println(string(res))

感谢jabbson的回答。 我只是想从一个.go脚本中运行简单的Linux grep命令,但这似乎是不可能的……

如果在Linux上运行该命令,我得到: NS-000498:$ sudo grep ^protected-mode /etc/redis/*.conf | wc -l 5 我只是想获取那个“5”以便在.go脚本中进行后续分析。 这样说得通吗?

问题在于你错误地使用了管道(|)和 wc 命令。在 exec.Command 中,管道符号 | 被当作普通参数传递给了 grep,而不是作为 shell 管道。你需要通过 shell 来执行命令,或者分别执行两个命令并通过 Go 代码连接它们。

以下是两种解决方法:

方法1:通过 shell 执行命令

cmd := exec.Command("sh", "-c", "sudo grep '^protected-mode' /etc/redis/*.conf | wc -l")
protectedModeStatusByte, err := cmd.Output()
if err != nil {
    // 处理错误,例如命令执行失败或权限问题
    fmt.Printf("命令执行失败: %v\n", err)
    return
}
protectedModeStatus := strings.TrimSpace(string(protectedModeStatusByte))
fmt.Printf("protected-mode Status: %s\n", protectedModeStatus)

方法2:分别执行命令并手动处理数据

// 执行 grep 命令
grepCmd := exec.Command("sudo", "grep", "-h", "^protected-mode", "/etc/redis/*.conf")
grepOutput, err := grepCmd.Output()
if err != nil {
    // grep 可能在没有匹配时返回非零退出码,需要根据情况处理
    if exitErr, ok := err.(*exec.ExitError); ok && exitErr.ExitCode() == 1 {
        // 没有匹配项,grep 返回 1 是正常情况
        protectedModeStatus = "0"
    } else {
        fmt.Printf("grep 命令执行失败: %v\n", err)
        return
    }
} else {
    // 统计行数
    lines := strings.Count(string(grepOutput), "\n")
    protectedModeStatus = strconv.Itoa(lines)
}
fmt.Printf("protected-mode Status: %s\n", protectedModeStatus)

关键点说明:

  1. 管道 | 是 shell 的功能,exec.Command 默认不通过 shell 执行命令
  2. 使用 sh -c 可以将整个命令字符串交给 shell 解释执行
  3. strings.TrimSpace() 用于去除输出中的换行符和空格
  4. 方法2更详细地处理了错误情况,包括 grep 没有找到匹配时的退出码1

建议使用方法1,除非你有特殊需求要避免使用 shell。同时注意 sudo 可能需要终端输入密码,如果配置了免密码 sudo 或在非交互环境下运行,请确保权限正确。

回到顶部