用Go去调用一些外部的命令其实很愉快的,这遍文章就总结一下我自己日常用的比较多的几种方法。
关于Unix标准输入输出 在具体聊os/exec的使用前,了解一下shell的标准输出是很有必要的。
我们平常会用到或看到这样的命令:
$ ls xxx 1>out.txt 2>&1 $ nohup xxx 2>&1 & 你知道这里1,2含义么?
其实这里的1,2指的就是Unix文件描述符。文件描述符其实就一数字,每一个文件描述符代表的都是一个文件。如果你打开100个文件,你就会获取到100个文件描述符。
这里需要注意的一点就是,在Unix中一切皆文件。当然,这里我们不必去深究,我们需要知道的是1,2代表的是标准输出stdout与标准错误输出stderr。还有0代表标准输入stdin。
在os/exec中就用到了Stdin,Stdout,Stderr,这些基本Unix知识或能帮助我们更好理解这些参数。
os/exec os/exec包内容并不多,我们大概过一下。
LookPath(file string) (string, error)
寻找可执行文件路径,如果你指定的可执行文件在$PATH中,就会返回这个可执行文件的相对/绝对路径;如果你指定的是一个文件路径,他就是去判断文件是否可读取/执行,返回的是一样的路径。
在我们需要使用一些外部命令/可执行文件的时候,我们可以先使用该函数判断一下该命令/可执行文件是否有效。
Command(name string, arg …string) *Cmd
使用你输入的参数,返回Cmd指针,可用于执行Cmd的方法。
这里name就是我们的命令/可执行文件,后面的参数可以一个一个输入。
CommandContext(ctx context.Context, name string, arg …string) *Cmd
和上面功能一样,不过我们可以用上下文做一些超时等控制。
之后几个就是Cmd的一些方法。
(c *Cmd) CombinedOutput() ([]byte, error) 将标准输出,错误输出一起返回;
(c *Cmd) Output() ([]byte, error) 输出标准输出,错误从error返回;
(c *Cmd) Run() error 执行任务,等待执行完成;
(c *Cmd) Start() error, (c *Cmd) Wait() error 前者执行任务,不等待完成,用后者等待,并释放资源;
(c *Cmd) StderrPipe() (io....