一尘不染

如何在Go(golang)中直接调用系统外壳?

go

根据golang文档,当您使用exec.Command()时,go不会调用系统的外壳程序。

从“ os / exec”软件包上的golang.org文档中:

与使用C和其他语言进行“系统”库调用不同,os /
exec软件包有意不调用系统外壳程序,并且不展开任何glob模式或处理其他通常由外壳程序完成的扩展,管道或重定向。

这带来了问题。由于这种设计选择,您在执行命令时不能使用管道。因此,以下代码无法按预期执行。

package main

import (
        "fmt"
        "os/exec"
)

func main() {
        exec.Command("echo", "Hello", ">>", "~/thing").Run()
        cmdOut, _ := exec.Command("cat", "~/thing").Output()

        fmt.Println(cmdOut)
}

它不会打印出应包含单词“ Hello”的文件内容,而是打印出空白的换行符。我已经尝试过像这样直接调用bash:

package main

import (
        "fmt"
        "os/exec"
)

func main() {
        exec.Command("bash", "-c", "echo", "Hello", ">>", "~/thing").Run()
        cmdOut, _ := exec.Command("cat", "~/thing").Output()

        fmt.Println(cmdOut)
}

但是,这会产生与原始代码相同的结果。使用golang时如何直接调用系统外壳?


阅读 239

收藏
2020-07-02

共1个答案

一尘不染

第二个参数应该是一个字符串。在shell命令中,您也需要将其作为一个字符串传递。也~由bash解释。您可以放心地假设它sh存在。Bash
shell不是必须的。

package main

import (                                                                                                                                                                  
 "fmt"                                                                                                                                                                    
 "os/exec"                                                                                                                                                                
)

func main() {                                                                                                                                                             
 exec.Command("sh", "-c", "echo Hello >> ~/thing").Run()                                                                                                                  
 cmdOut, _ := exec.Command("sh", "-c", "cat ~/thing").Output()                                                                                                            
 fmt.Println(cmdOut)                                                                                                                                                      
}
2020-07-02