exec

最后更新于:2022-04-02 02:45:20

[TOC] ## 语法 ``` type Cmd struct { // 该字段不能为空,如为相对路径会相对于Dir字段。 Path string // Args保管命令的参数,包括命令名作为第一个参数;如果为空切片或者nil,相当于无参数命令。 // // 典型用法下,Path和Args都应被Command函数设定。 Args []string // Env指定进程的环境,如为nil,则是在当前进程的环境下执行。 Env []string // Dir指定命令的工作目录。如为空字符串,会在调用者的进程当前目录下执行。 Dir string Stdin io.Reader Stdout io.Writer Stderr io.Writer // ExtraFiles指定额外被新进程继承的已打开文件流,不包括标准输入、标准输出、标准错误输出。 // 如果本字段非nil,entry i会变成文件描述符3+i。 // // BUG: 在OS X 10.6系统中,子进程可能会继承不期望的文件描述符。 // http://golang.org/issue/2603 ExtraFiles []*os.File // SysProcAttr保管可选的、各操作系统特定的sys执行属性。 // Run方法会将它作为os.ProcAttr的Sys字段传递给os.StartProcess函数。 SysProcAttr *syscall.SysProcAttr // Process是底层的,只执行一次的进程。 Process *os.Process // ProcessState包含一个已经存在的进程的信息,只有在调用Wait或Run后才可用。 ProcessState *os.ProcessState } func (c *Cmd) StdinPipe() (io.WriteCloser, error) func (c *Cmd) StdoutPipe() (io.ReadCloser, error) func (c *Cmd) StderrPipe() (io.ReadCloser, error) func (c *Cmd) Run() error // 阻塞直到完成 func (c *Cmd) Start() error // 不会等待该命令完成即返回 func (c *Cmd) Wait() error func (c *Cmd) Output() ([]byte, error) func (c *Cmd) CombinedOutput() ([]byte, error) ``` ## 实例 ### LookPath 查看命令是否存在 ``` path, err := exec.LookPath("ls") if err != nil { fmt.Printf("didn't find 'ls' executable\n") } else { fmt.Printf("'ls' executable is in '%s'\n", path) } ``` ### Stdin / Stdout 指定输入输出 实例1:通过 Stdin和Stdout 指定输入,输出 ``` var out bytes.Buffer // tr命令 小写转大写 cmd := exec.Command("tr", "a-z", "A-Z") cmd.Stdin = strings.NewReader("some input") cmd.Stdout = &out err := cmd.Run() if err != nil { log.Fatal(err) } fmt.Printf("in all caps: %q\n", out.String()) // in all caps: "SOME INPUT" ``` ### 设置环境变量 ``` cmd := exec.Command("prog") cmd.Env = append(os.Environ(), "FOO=duplicate_value", // ignored "FOO=actual_value", // this value is used ) if err := cmd.Run(); err != nil { log.Fatal(err) } ``` ### Output 直接输出 ``` out, err := exec.Command("date").Output() if err != nil { log.Fatal(err) } fmt.Printf("The date is %s\n", out) ``` ### Start 需要 Wait ``` cmd := exec.Command("sleep", "5") err := cmd.Start() if err != nil { log.Fatal(err) } log.Printf("Waiting for command to finish...") err = cmd.Wait() log.Printf("Command finished with error: %v", err) ``` ### CommandContext ``` ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() if err := exec.CommandContext(ctx, "sleep", "5").Run(); err != nil { // This will fail after 100 milliseconds. The 5 second sleep // will be interrupted. } ```
';