os/exec 执行命令、管道

在windows执行命令

cmd0 := exec.Command("cmd.exe","/C", "dir")

 

前两个参数是固定的,后面+命令

 

在linux中

cmd0 := exec.Command("ps","aux")

也可以加入一些参数

cmd0 := exec.Command("echo","-n", "你好")

 

使用Command 方法可以返回一个 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
    // 内含隐藏或非导出字段
}

  

可以通过这个结构体的 方法获取 标准输出 、标准输出、标准错误输出的管道

 

	ioWriterCloser ,err := cmd0.StdinPipe()
	ioReaderCloser,err := cmd0.StderrPipe()
	ioReaderCloser,err := cmd0.StdoutPipe()  

 

管道方法返回 两种接口。

我们可以利用接口获取数据、写入其他命令

 

获取数据

	cmd0 := exec.Command("cmd.exe","/C", "dir")
	ioR ,err := cmd0.StderrPipe()
	if err != nil {
		panic("err")
	}

	r := bufio.NewReader(ioR)
	l ,_,err := r.ReadLine()
	if err != nil {
		panic("err")
	}

  

也可以通过 返回ioReader 接口 直接读数据,读到结尾判断EOF就可以了。

 

将一个命令的输出作为另外一个命令的输入 相当于 #ps aux | grep apipe

	cmd1 := exec.Command("ps","aux")
	cmd2 := exec.Command("grep","apipe")
	var outPutBuf1 bytes.Buffer

	//指定命令的标准输出
	cmd1.Stdout = &outPutBuf1

	//指定cmd2的标准输入
	cmd2.Stdin = &outPutBuf1

  

管道还有os.Pipe()   、io.Pipe()   后者是基于内存的有原子性保障的单独管道

 

还有就是一个很关键的字段 cmd.ExtraFiles

可以像要打开的新进程中添加文件流

cmd.ExtraFiles = []*os.File{f}

  

文件流使用os.NewFile(3,"")  打开  ,因为前几个文件描述符 0、1、2 默认为 标准输入、标准输出、标准错误输出

 

posted on 2020-04-15 14:52  thotf  阅读(906)  评论(0)    收藏  举报

导航