NotePublic/Software/Development/Language/Go/Package/OS/Exec/Golang_执行外部程序.md

88 lines
2.5 KiB
Markdown
Raw Normal View History

# 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/)