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

2.5 KiB
Raw Blame History

Golang 执行外部程序

需要使用 os/exec 包。

1.基本用法

示例如下:

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.外部程序绑定标准输入输出

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 的外部命令调用

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使用指南