里用ping进程为例,在main函数中创建ping程序,然后将ping的执行结果通过管道(pipe)传递给主程序.主程序读取结果,然后打印,最后通过主程序发送系统信号(syscall.Signal)来结束ping.

    cmd1 := exec.Command("ping", "")      //创建子进程
    ppReader, err := cmd1.StdoutPipe()            //创建管道,ppReader为io.ReaderCloser类型
    var bufReader = bufio.NewReader(ppReader)     //创建带缓冲的Reader
    if err != nil {
        fmt.Printf("create cmd stdoutpipe failed,error:%sn", err)
        os.Exit(1)
    }
    err = cmd1.Start()   //启动cmd1
    if err != nil {
        fmt.Printf("cannot start cmd1,error:%sn", err)
        os.Exit(1)
    }

创建协程读取输出通过管道传输的数据

    go func() {
        var buffer []byte = make([]byte, 4096)        for {
            n, err := bufReader.Read(buffer)   //读取数据到buffer中
            if err != nil { 
                if err == io.EOF {      //管道关闭后会出现io.EOF错误
                    fmt.Printf("pipi has Closedn")                    break
                } else {
                    fmt.Println("Read content failed")
                }
            }
            fmt.Print(string(buffer[:n]))
        }
    }()

主程序发送信号给子进程,停止cmd1的运行

    time.Sleep(10 * time.Second)      //让子进程运行10秒
    err = stopProcess(cmd1)      //    停止子进程
    if err != nil {
        fmt.Printf("stop child process failed,error:%s", err)
        os.Exit(1)
    }
    cmd1.Wait()      //能让cmd1执行到结束,测试stopProcess是否成功,如果没有stopProcess,程序和子进程会一直执行
    time.Sleep(1 * time.Second)     //让协程能读取关闭子进程时最后一次传输的数据

stopProcess的内容

func stopProcess(cmd *exec.Cmd) error {
    pro, err := os.FindProcess(cmd.Process.Pid)     //通过pid获取子进程
    if err != nil {        return err
    }
    err = pro.Signal(syscall.SIGINT)   //给子进程发送信号使之结束
    if err != nil {        return err
    }
    fmt.Printf("结束子进程%s成功n", cmd.Path)    return nil}

完整代码段

package main

import (    "bufio"
    "fmt"
    "io"
    "os"
    "os/exec"
    "time"

    "syscall")

func main() {
    cmd1 := exec.Command("ping", "")
    ppReader, err := cmd1.StdoutPipe()
    defer ppReader.Close()
    var bufReader = bufio.NewReader(ppReader)    if err != nil {
        fmt.Printf("create cmd stdoutpipe failed,error:%sn", err)
        os.Exit(1)
    }
    err = cmd1.Start()    if err != nil {
        fmt.Printf("cannot start cmd1,error:%sn", err)
        os.Exit(1)
    }
    go func() {
        var buffer []byte = make([]byte, 4096)        for {
            n, err := bufReader.Read(buffer)            if err != nil {                if err == io.EOF {
                    fmt.Printf("pipi has Closedn")                    break
                } else {
                    fmt.Println("Read content failed")
                }
            }
            fmt.Print(string(buffer[:n]))
        }
    }()
    time.Sleep(10 * time.Second)
    err = stopProcess(cmd1)    if err != nil {
        fmt.Printf("stop child process failed,error:%s", err)
        os.Exit(1)
    }
    cmd1.Wait()
    time.Sleep(1 * time.Second)
}

func stopProcess(cmd *exec.Cmd) error {
    pro, err := os.FindProcess(cmd.Process.Pid)    if err != nil {        return err
    }
    err = pro.Signal(syscall.SIGINT)    if err != nil {        return err
    }
    fmt.Printf("结束子进程%s成功n", cmd.Path)    return nil}

运行结果:

PING  (180.97.33.107) 56(84) bytes of data.64 bytes from 180.97.33.107 (180.97.33.107): icmp_seq=1 ttl=55 time=35.3 ms64 bytes from 180.97.33.107 (180.97.33.107): icmp_seq=2 ttl=55 time=34.7 ms64 bytes from 180.97.33.107 (180.97.33.107): icmp_seq=3 ttl=55 time=34.2 ms64 bytes from 180.97.33.107 (180.97.33.107): icmp_seq=4 ttl=55 time=39.6 ms64 bytes from 180.97.33.107 (180.97.33.107): icmp_seq=5 ttl=55 time=34.4 ms64 bytes from 180.97.33.107 (180.97.33.107): icmp_seq=6 ttl=55 time=34.2 ms64 bytes from 180.97.33.107 (180.97.33.107): icmp_seq=7 ttl=55 time=34.2 ms64 bytes from 180.97.33.107 (180.97.33.107): icmp_seq=8 ttl=55 time=34.2 ms64 bytes from 180.97.33.107 (180.97.33.107): icmp_seq=9 ttl=55 time=34.2 ms64 bytes from 180.97.33.107 (180.97.33.107): icmp_seq=10 ttl=55 time=34.2 ms
结束子进程/bin/ping成功

---  ping statistics ---10 packets transmitted, 10 received, 0% packet loss, time 9012ms
rtt min/avg/max/mdev = 34.206/34.967/39.689/1.632 ms
pipi has Closed

Process finished with exit code 0