2020-12-21 14:08:24 +08:00
|
|
|
|
# Golang 执行外部程序
|
|
|
|
|
|
|
|
|
|
需要使用 os/exec 包。
|
|
|
|
|
|
2021-08-11 14:31:39 +08:00
|
|
|
|
## 1.基本用法
|
|
|
|
|
|
2020-12-21 14:08:24 +08:00
|
|
|
|
示例如下:
|
|
|
|
|
|
|
|
|
|
```go
|
|
|
|
|
func MakeCmd(name string, arg ...string) *exec.Cmd {
|
|
|
|
|
cmd := exec.Command(name, arg...)
|
2021-05-26 22:48:00 +08:00
|
|
|
|
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"))
|
2020-12-21 14:08:24 +08:00
|
|
|
|
return cmd
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|
cmd := MakeCmd("ls", "-l", "/")
|
|
|
|
|
output, _ := cmd.Output()
|
2021-05-26 22:48:00 +08:00
|
|
|
|
fmt.Println(string(output))
|
2020-12-21 14:08:24 +08:00
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
exec.Cmd 有 Start、Wait、Run、Output 等方法,其中
|
|
|
|
|
|
|
|
|
|
* Start:非阻塞执行;
|
|
|
|
|
* Wait:阻塞进程,等待命令执行结束, 经常与 Star 配合使用;
|
|
|
|
|
* Run:阻塞进程,直到命令执行结束,相当于 Start+Wait 的组合;
|
|
|
|
|
* Output:阻塞进程,直到命令执行结束,比 Run 方法多返回程序的 stdout。
|
2021-08-11 14:31:39 +08:00
|
|
|
|
|
|
|
|
|
## 2.带 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()
|
|
|
|
|
}
|
|
|
|
|
```
|