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



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

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

与来自C和其他语言的"系统"库调用不同,os/exec包有意不调用系统shell,也不扩展任何glob模式或处理通常由shell执行的其他扩展、管道或重定向。

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

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)                                                                                                                                                      
}

最新更新