golang os/exec StdoutPipe StdinPipe 执行命令 管道

go语言执行命令

go在执行Cmd/Shell命令时,跟一些语言是有区别的.
在不调用shell的情况下,需要自己对每个步骤手动写

我的目的是执行

netstat -aon | findstr :80   //Win
netstat -ano | grep :80  //Unix

由于中间加了管道| 所以许多资料都不能满足我的想法
所以自己手动找了许多资料实现了

过程

  • cmdNetstat
  • cmdGrep
  • netstatOutPutPip (输出管道)
  • grepInPutPip(输入管道)
  • cmdNetstat.Start
  • 得到输出管道中的数据
  • cmdGrep.Start
  • 将得到的数据写入另一个管道
  • 得到最后的结果数据

代码


func ShellCmdNetstat(port int) ([]byte, error) {
    cmdNetstat := exec.Command("netstat", "/a", "/n", "/o") // netstat -ano

    var cmdGrep *exec.Cmd
    if runtime.GOOS == "windows" {
        cmdGrep = exec.Command("findstr", fmt.Sprintf(":%d ", port)) // win:    findstr ":80 "
    } else if runtime.GOOS == "linux" {
        cmdGrep = exec.Command("grep", fmt.Sprintf(":%d ", port)) // unix:  grep ":80"
    }

    netstatOutPutPip, _ := cmdNetstat.StdoutPipe() // netstat out pipe
    grepInPutPip, _ := cmdGrep.StdinPipe()         // grep in pipe

    if err := cmdNetstat.Start(); err != nil {
        return make([]byte, 0), err
    }

    data, _ := ioutil.ReadAll(netstatOutPutPip)

    if err := cmdNetstat.Wait(); err != nil {
        fmt.Println("cmdNetstat.Wait()", err)
        return make([]byte, 0), err
    }

    var grepOutBuffer bytes.Buffer
    cmdGrep.Stdout = &grepOutBuffer
    if err := cmdGrep.Start(); err != nil {
        fmt.Println(err)
        return make([]byte, 0), err
    }

    grepInPutPip.Write(data) // cmdNetstat out >> grepInPutPip in

    // 这行代码让你原地打转2天
    // The pipe will be closed automatically after Wait sees the command exit.
    // A caller need only call Close to force the pipe to close sooner.
    // For example, if the command being run will not exit until standard input
    // is closed, the caller must close the pipe.
    grepInPutPip.Close() //  This Is So Important!!!  命令在输入关闭后才会执行返回时需要显式关闭管道。

    if err := cmdGrep.Wait(); err != nil {
        return make([]byte, 0), err
    }
    return grepOutBuffer.Bytes(), nil
}




© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容