57

golang os/exec 执行外部命令

 5 years ago
source link: https://studygolang.com/articles/20070?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

exec包执行外部命令,它将os.StartProcess进行包装使得它更容易映射到stdin和stdout,并且利用pipe连接i/o.

func LookPath(file string) (string, error) //LookPath在环境变量中查找科执行二进制文件,如果file中包含一个斜杠,则直接根据绝对路径或者相对本目录的相对路径去查找

1.  func main() {  
2.  f, err := exec.LookPath("ls")  
3.  if err != nil {  
4.  fmt.Println(err)  
5.  }  
6.  fmt.Println(f) //  /bin/ls  
7.  }

type Cmd//表示一个正在准备或者正在运行的外部命令

1.  type Cmd struct {  
2.  Path         string   //运行命令的路径,绝对路径或者相对路径  
3.  Args         []string   // 命令参数  
4.  Env          []string         //进程环境,如果环境为空,则使用当前进程的环境  
5.  Dir          string   //指定command的工作目录,如果dir为空,则comman在调用进程所在当前目录中运行  
6.  Stdin        io.Reader  //标准输入,如果stdin是nil的话,进程从null device中读取(os.DevNull),stdin也可以时一个文件,否则的话则在运行过程中再开一个goroutine去  
7.  //读取标准输入  
8.  Stdout       io.Writer       //标准输出  
9.  Stderr       io.Writer  //错误输出,如果这两个(Stdout和Stderr)为空的话,则command运行时将响应的文件描述符连接到os.DevNull  
10.  ExtraFiles   []*os.File     
11.  SysProcAttr  *syscall.SysProcAttr  
12.  Process      *os.Process    //Process是底层进程,只启动一次  
13.  ProcessState *os.ProcessState  //ProcessState包含一个退出进程的信息,当进程调用Wait或者Run时便会产生该信息.  
14.  }

func Command(name string, arg ...string) *Cmd//command返回cmd结构来执行带有相关参数的命令,它仅仅设定cmd结构中的Path和Args参数,如果name参数中不包含路径分隔符,command使用LookPath来解决路径问题,否则的话就直接使用name;Args直接跟在command命令之后,所以在Args中不许要添加命令.

1.  func main() {  
2.  cmd := exec.Command("tr", "a-z", "A-Z")  
3.  cmd.Stdin = strings.NewReader("some input")  
4.  var out bytes.Buffer  
5.  cmd.Stdout = &out  
6.  err := cmd.Run()  
7.  if err != nil {  
8.  log.Fatal(err)  
9.  }  
10.  fmt.Printf("in all caps: %q\n", out.String())  //in all caps: "SOME INPUT"  
11.  }

func (c *Cmd) CombinedOutput() ([]byte, error)//运行命令,并返回标准输出和标准错误

1.  func main() {  
2.  cmd := exec.Command("ls")  //查看当前目录下文件  
3.  out, err := cmd.CombinedOutput()  
4.  if err != nil {  
5.  fmt.Println(err)  
6.  }  
7.  fmt.Println(string(out))  
8.  }

func (c *Cmd) Output() ([]byte, error)//运行命令并返回其标准输出

1.  func main() {  
2.  cmd := exec.Command("ls") ///查看当前目录下文件  
3.  out, err := cmd.Output()  
4.  if err != nil {  
5.  fmt.Println(err)  
6.  }  
7.  fmt.Println(string(out))  
8.  }

注意:Output()和CombinedOutput()不能够同时使用,因为command的标准输出只能有一个,同时使用的话便会定义了两个,便会报错

func (c *Cmd) Run() error//开始指定命令并且等待他执行结束,如果命令能够成功执行完毕,则返回nil,否则的话边会产生错误

func (c *Cmd) Start() error//使某个命令开始执行,但是并不等到他执行结束,这点和Run命令有区别.然后使用Wait方法等待命令执行完毕并且释放响应的资源

1.  func main() {  
2.  cmd := exec.Command("ls")  
3.  cmd.Stdout = os.Stdout //  
4.  cmd.Run()  
5.  fmt.Println(cmd.Start()) //exec: already started  
6.  }

注:一个command只能使用Start()或者Run()中的一个启动命令,不能两个同时使用.

func (c *Cmd) StderrPipe() (io.ReadCloser, error)//StderrPipe返回一个pipe,这个管道连接到command的标准错误,当command命令退出时,Wait将关闭这些pipe

func (c *Cmd) StdinPipe() (io.WriteCloser, error)//StdinPipe返回一个连接到command标准输入的管道pipe

1.  package main  

3.  import (  
4.  "fmt"  
5.  "os"  
6.  "os/exec"  
7.  )
9.  func main() {  
10.  cmd := exec.Command("cat")  
11.  stdin, err := cmd.StdinPipe()  
12.  if err != nil {  
13.  fmt.Println(err)  
14.  }  
15.  _, err = stdin.Write([]byte("tmp.txt"))  
16.  if err != nil {  
17.  fmt.Println(err)  
18.  }  
19.  stdin.Close()  
20.  cmd.Stdout = os.Stdout     //终端标准输出tmp.txt  
21.  cmd.Start()  
22.  }

func (c *Cmd) StdoutPipe() (io.ReadCloser, error) //StdoutPipe返回一个连接到command标准输出的管道pipe

1.  func main() {  
2.  cmd := exec.Command("ls")  
3.  stdout, err := cmd.StdoutPipe()  //指向cmd命令的stdout  
4.  cmd.Start()  
5.  content, err := ioutil.ReadAll(stdout)  
6.  if err != nil {  
7.  fmt.Println(err)  
8.  }  
9.  fmt.Println(string(content))     //输出ls命令查看到的内容  
10.  }

func (c *Cmd) Wait() error//Wait等待command退出,他必须和Start一起使用,如果命令能够顺利执行完并顺利退出则返回nil,否则的话便会返回error,其中Wait会是放掉所有与cmd命令相关的资源

type Error //Error返回科执行二进制文件名字不能够执行的原因的错误

1.  type Error struct {  
2.  Name string  
3.  Err  error  
4.  }

func (e *Error) Error() string

type ExitError//一个command不能够正常退出的error

1.  type ExitError struct {  
2.  *os.ProcessState  
3.  }

func (e *ExitError) Error() string


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK