# Golang 执行外部程序 需要使用 os/exec 包。 ## 1.基本用法 示例如下: ```go func MakeCmd(name string, arg ...string) *exec.Cmd { cmd := exec.Command(name, arg...) cmd.Env = append(cmd.Env, os.Getenv("USER")) cmd.Env = append(cmd.Env, os.Getenv("HOME")) cmd.Env = append(cmd.Env, os.Getenv("SHELL")) cmd.Env = append(cmd.Env, os.Getenv("LOGNAME")) cmd.Env = append(cmd.Env, os.Getenv("PATH")) return cmd } func main() { cmd := MakeCmd("ls", "-l", "/") output, _ := cmd.Output() fmt.Println(string(output)) } ``` exec.Cmd 有 Start、Wait、Run、Output 等方法,其中 * Start:非阻塞执行; * Wait:阻塞进程,等待命令执行结束, 经常与 Star 配合使用; * Run:阻塞进程,直到命令执行结束,相当于 Start+Wait 的组合; * Output:阻塞进程,直到命令执行结束,比 Run 方法多返回程序的 stdout。 ## 2.外部程序绑定标准输入输出 ```go func MakeCmd(name string, arg ...string) *exec.Cmd { cmd := exec.Command(name, arg...) // 绑定标准输入输出 cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Env = append(cmd.Env, os.Getenv("USER")) cmd.Env = append(cmd.Env, os.Getenv("HOME")) cmd.Env = append(cmd.Env, os.Getenv("SHELL")) cmd.Env = append(cmd.Env, os.Getenv("LOGNAME")) cmd.Env = append(cmd.Env, os.Getenv("PATH")) return cmd } func main() { cmd := MakeCmd("ls", "-l", "./") cmd.Run() } ``` ## 3.带 Cancel 的外部命令调用 ```go func MakeCmdWithCancel(name string, arg ...string) (*exec.Cmd, context.CancelFunc) { ctx, cancel := context.WithCancel(context.Background()) cmd := exec.CommandContext(ctx, name, arg...) cmd.Env = append(cmd.Env, "USER=root") cmd.Env = append(cmd.Env, "HOME=/home/root") cmd.Env = append(cmd.Env, "SHELL=/bin/sh") cmd.Env = append(cmd.Env, "SHLVL=1") cmd.Env = append(cmd.Env, "LOGNAME=root") cmd.Env = append(cmd.Env, "XDG_RUNTIME_DIR=/run/user/0") cmd.Env = append(cmd.Env, "PATH=/usr/local/bin:/usr/bin:/bin:/xt/scripts:/usr/local/sbin:/usr/sbin:/sbin:/xt/scripts") return cmd, cancel } func main() { // Sleep 20s sleep, cancel := MakeCmdWithCancel("sleep", "20") sleep.Start() // 3s 后 Cancel 掉 time.Sleep(3 * time.Second) cancel() // 会立刻退出 sleep.Wait() } ``` ## 4.外部参考资料 1. [Go标准库os/exec使用指南](https://honeypps.com/golang/go-standard-lib-os-exec-guide/)