Go(golang)中如何直接调用系统shell?

How to directly invoke the system shell in Go (golang)?

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

来自 golang.org 关于 "os/exec" 软件包的文档:

Unlike the "system" library call from C and other languages, the os/exec package intentionally does not invoke the system shell and does not expand any glob patterns or handle other expansions, pipelines, or redirections typically done by shells.

这是一个问题。由于这种设计选择,您不能在执行命令时使用管道。因此,以下代码未按预期执行。

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时如何直接调用系统shell?

第二个参数应该是一个字符串。在 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)                                                                                                                                                      
}