Package exec runs external commands. It wraps os.StartProcess to make it easier to remap stdin and stdout, connect I/O with pipes, and do other adjustments.

Unlike the "system" library call from C and other languages, the os/exec package intentionally does not invoke the system shell and does not expand any glob patterns or handle other expansions, pipelines, or redirections typically done by shells. The package behaves more like C's "exec" family of functions. To expand glob patterns, either call the shell directly, taking care to escape any dangerous input, or use the path/filepath package's Glob function. To expand environment variables, use package os's ExpandEnv.

Note that the examples in this package assume a Unix system. They may not run on Windows, and they do not run in the Go Playground used by golang.org and godoc.org.

func LookPath

func LookPath(file string) (string, error)

在环境变量PATH指定的目录中搜索可执行文件,如file中有斜杠,则只在当前目录搜索。

即:默认在系统的环境变量里查找给定的可执行命令文件,如果查找到返回路径,否则报错,unix是$PATH,windows是$PATH$。可提供相对路径下进行查找,并返回相对路径

type Cmd

type Cmd struct {
// Path是将要执行的命令的路径。
//
// 该字段不能为空,如为相对路径会相对于Dir字段。
Path string
// Args保管命令的参数,包括命令名作为第一个参数;如果为空切片或者nil,相当于无参数命令。
//
// 典型用法下,Path和Args都应被Command函数设定。
Args []string
// Env指定进程的环境,如为nil,则是在当前进程的环境下执行。
Env []string
// Dir指定命令的工作目录。如为空字符串,会在调用者的进程当前目录下执行。
Dir string
// Stdin指定进程的标准输入,如为nil,进程会从空设备读取(os.DevNull)
Stdin io.Reader
// Stdout和Stderr指定进程的标准输出和标准错误输出。
//
// 如果任一个为nil,Run方法会将对应的文件描述符关联到空设备(os.DevNull)
//
// 如果两个字段相同,同一时间最多有一个线程可以写入。
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
// 内含隐藏或非导出字段
}

Cmd代表一个正在准备或者在执行中的外部命令。

注:exec在执行调用系统命令时,会先对需要执行的操作进行一次封装,然后在执行。封装后的命令对象具有以上struct属性。而封装方式即使用下边的command函数。

func Command

func Command(name string, arg ...string) *Cmd

函数返回一个*Cmd,用于使用给出的参数执行name指定的程序。返回值只设定了Path和Args两个参数。

如果name不含路径分隔符(如果不是相对路径),将使用LookPath获取完整路径(就是用默认的全局变量路径);否则直接使用name。参数arg不应包含命令名。

cmd := exec.Command("go","version")
fmt.Println(cmd.Args, cmd.Path)

注:在调用命令执行封装时,如果不提供相对路径,系统会使用LookPath获取完整路径;即这里可以给一个相对路径。

以上操作只会将命令进行封装,相当于告诉系统将进行哪些操作,但是执行时无法获取相关信息,因此我们还需要连接到命令执行时相关的输入输出pipe。################################################################################################

我们可以通过指定一个对象连接到对应的管道进行传输参数(stdinpipe),获取输出(stdoutpipe),获取错误(stderrpipe)

func (*Cmd) StdinPipe

func (c *Cmd) StdinPipe() (io.WriteCloser, error)  //err 返回的是执行函数时的错误
package main

import (
"fmt"
"os"
"os/exec"
) func main() {
cmd := exec.Command("cat")
stdin, err := cmd.StdinPipe() //指定stdin连接StdinPipe,然后操作stdin就实现了对command的参数传递
if err != nil {
fmt.Println(err)
}
_, err = stdin.Write([]byte("tmp.txt")) //字节切片
if err != nil {
fmt.Println(err)
}
stdin.Close()
cmd.Stdout = os.Stdout //终端标准输出tmp.txt
cmd.Start()
}

StdinPipe方法返回一个在命令Start后与命令标准输入关联的管道。Wait方法获知命令结束后会关闭这个管道。必要时调用者可以调用Close方法来强行关闭管道,例如命令在输入关闭后才会执行返回时需要显式关闭管道。

func (*Cmd) StdoutPipe

func (c *Cmd) StdoutPipe() (io.ReadCloser, error)    //err 返回的是执行函数时的错误
func main() {
cmd := exec.Command("ls")
stdout, err := cmd.StdoutPipe()  //指向cmd命令的stdout,然后就可以从stdout读出信息
cmd.Start()
content, err := ioutil.ReadAll(stdout)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(content)) //输出ls命令查看到的内容
}

StdoutPipe方法返回一个在命令Start后与命令标准输出关联的管道。Wait方法获知命令结束后会关闭这个管道,一般不需要显式的关闭该管道。但是在从管道读取完全部数据之前调用Wait是错误的;同样使用StdoutPipe方法时调用Run函数也是错误的。

func (*Cmd) StderrPipe

func (c *Cmd) StderrPipe() (io.ReadCloser, error)   //err 返回的是执行函数时的错误
import (
"fmt"
"io/ioutil"
"os/exec"
) func main() {
c := exec.Command("mv", "hello")
i, err := c.StderrPipe()
if err != nil {
fmt.Printf("Error: %s\n", err)
return
}
if err = c.Start(); err != nil {    //表示命令正确执行了
fmt.Printf("Error: %s\n", err)
}
b, _ := ioutil.ReadAll(i)        //读取命令执行的返回结果(命令执行结果的错误信息)
if err := c.Wait(); err != nil {
fmt.Printf("Error: %s\n", err)   //Error: exit status 1 mv: missing file argument Try `mv --help' for more information.
}
fmt.Println(string(b))
}

StderrPipe方法返回一个在命令Start后与命令标准错误输出关联的管道。Wait方法获知命令结束后会关闭这个管道,一般不需要显式的关闭该管道。但是在从管道读取完全部数据之前调用Wait是错误的;同样使用StderrPipe方法时调用Run函数也是错误的

#################################################################

func (*Cmd) Run

func (c *Cmd) Run() error

Run执行c包含的命令,并阻塞直到完成。

如果命令成功执行,stdin、stdout、stderr的转交没有问题,并且返回状态码为0,方法的返回值为nil【执行Run函数的返回状态,正确执行Run函数,并不代表正确执行了命令】;如果函数没有执行或者执行失败,会返回*ExitError类型的错误;否则返回的error可能是表示I/O问题。

即:该命令只会执行且阻塞到执行结束,如果执行函数有错则返回报错信息,没错则返回nil,并不会返回执行结果。

func (*Cmd) Start

func (c *Cmd) Start() error

Start开始执行c包含的命令,但并不会等待该命令完成即返回。Wait方法会返回命令的返回状态码并在命令返回后释放相关的资源。

Example

func (*Cmd) Wait

func (c *Cmd) Wait() error

Wait会阻塞直到该命令执行完成,该命令必须是被Start方法开始执行的。

如果命令成功执行,stdin、stdout、stderr的转交没有问题,并且返回状态码为0,方法的返回值为nil;如果命令没有执行或者执行失败,会返回*ExitError类型的错误;否则返回的error可能是表示I/O问题。Wait方法会在命令返回后释放相关的资源。

func (*Cmd) Output

func (c *Cmd) Output() ([]byte, error)

执行命令并返回标准输出的切片。不用通过pipe方式获取命令的执行结果

import (
"fmt"
"os/exec"
) func main() {
c, err := exec.Command("date").Output()
if err != nil {
fmt.Println(err)
}
fmt.Println(string(c)) // Sat Jan 4 17:07:36 2014 这个是标准库里的例子
}

func (*Cmd) CombinedOutput

func (c *Cmd) CombinedOutput() ([]byte, error)

执行命令并返回标准输出和错误输出合并的切片。

Go基础篇【第5篇】: 内置库模块 exec的更多相关文章

  1. Go基础篇【第8篇】: 内置库模块 bytes [二]

    type Reader ¶ type Reader struct { // 内含隐藏或非导出字段 } Reader类型通过从一个[]byte读取数据,实现了io.Reader.io.Seeker.io ...

  2. Go基础篇【第1篇】: 内置库模块 OS

    os包提供了操作系统函数的不依赖平台的接口.设计为Unix风格的,虽然错误处理是go风格的:失败的调用会返回错误值而非错误码.通常错误值里包含更多信息.os包的接口规定为在所有操作系统中都是一致的.非 ...

  3. Go基础篇【第8篇】: 内置库模块 bytes [一]

    bytes包实现了操作[]byte的常用函数.本包的函数和strings包的函数相当类似. func Compare func Compare(a, b []byte) int Compare函数返回 ...

  4. Go基础篇【第6篇】: 内置库模块 flag

    import "flag" flag包实现了命令行参数的解析.每个参数认为一条记录,根据实际进行定义,到一个set集合.每条都有各自的状态参数. 在使用flag时正常流程: 1.  ...

  5. Go基础篇【第4篇】: 内置库模块 bufio

    bufio包实现了有缓冲的I/O.它包装一个io.Reader或io.Writer接口对象,创建另一个也实现了该接口,且同时还提供了缓冲和一些文本I/O的帮助函数的对象. 即:为了解决CPU与磁盘IO ...

  6. Go基础篇【第2篇】: 内置库模块 fmt

    fmt官方文档说明:https://studygolang.com/pkgdoc import "fmt" mt包实现了类似C语言printf和scanf的格式化I/O.格式化动作 ...

  7. Go内置库模块 flag

    import "flag" flag包实现了命令行参数的解析.每个参数认为一条记录,根据实际进行定义,到一个set集合.每条都有各自的状态参数. 在使用flag时正常流程: 1.  ...

  8. day05 模块以及内置常用模块用法

    内置常用模块详解: 1 time 2 datetime 3 random   4 os 5 sys 6 shutil 7 shelve 8 xml 9 configparser 10 hashlib ...

  9. 【CobaltStrike】对CobaltStrike内置功能模块的了解

    对CobaltStrike内置功能模块的了解 0x00 右键功能列表 Interact 打开beacon Access dump hashes 获取hash Elevate 提权 Golden Tic ...

随机推荐

  1. hadoop配置文件详解,安装及相关操作

    一.      Hadoop伪分布配置 1. 在conf/hadoop-env.sh文件中增加:export JAVA_HOME=/home/Java/jdk1.6  2.  在conf/core-s ...

  2. java web jsp学习笔记--概述-常用语法,指令,动作元素,隐式对象,域对象

     JSP学习笔记 1.什么是jsp JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术.JSP/Servlet规范.JS ...

  3. c# 【MVC】WebApi开发实例

    using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using S ...

  4. C++类中静态变量和静态方法使用介绍

    静态成员的提出是为了解决数据共享的问题.实现共享有许多方法,如:设置全局性的变量或对象是一种方法.但是,全局变量或对象是有局限性的.这一章里,我们主要讲述类的静态成员来实现数据的共享. 静态数据成员 ...

  5. 对着java并发包写.net并发包之原子类型实现

    众所周知,java1.5并发包通过volatile+CAS原理提供了优雅的并发支持.今天仔细想想.net也有volatile关键字保证内存的可见性,同时也有Interlocked提供了CAS的API, ...

  6. 机器学习技法:01 Linear Support Vector Machine

    Roadmap Course Introduction Large-Margin Separating Hyperplane Standard Large-Margin Problem Support ...

  7. 完整Log4Net配置信息

    <?xml version="1.0" encoding="utf-8" ?> <configuration> <configSe ...

  8. 关于scanf 与 cin gets(),getline()......输入输出字符串的区别

    很对人对于字符串的输入输出一直是比较模糊的,今天总结一下几个常用的输入流符号对于输入字符串时的区别: 1.scanf(),首先 它遇到空格或回车键(\n)就会结束,并且会将回车符算入字符串中: 2.c ...

  9. 【转】DMA和cache一致性

    DMA和cache一致性问题 Cache原理 CPU缓存(Cache Memory)是位于CPU与内存之间的临时存储器,它的容量比内存小的多但是交换速度却比内存要快得多.缓存的出现主要是为了解决CPU ...

  10. Visual Studio中让一个JS文件智能提示另一个JS文件中的成员

    当一个Web页面引用了两个JS文件(假如分别叫common.js和JScript1.js),如果JScript1.js中需要调用大量的common.js中的方法,这时候在JScript1.js中智能提 ...