• go channel 概述


    概述

    unix/linux OS 的一个进程的输出可以是另一个进程的输入,这些进程使用stdin与stdout设备作为通道,在进程之间传递数据。

    同样的,GO中有io.Reader与io.Writer两个接口,如果要对一个设备进行读/写,调用实现了这两个接口的方法即可。

    GO对管道的支持

    func t1()  {
        cmd0 := exec.Command("echo","-n","how are you")
        fmt.Println(cmd0)
    }

    exec.Command返回的对象的几个主要方法:

        // Stdin specifies the process's standard input.
        //
        // If Stdin is nil, the process reads from the null device (os.DevNull).
        //
        // If Stdin is an *os.File, the process's standard input is connected
        // directly to that file.
        //
        // Otherwise, during the execution of the command a separate
        // goroutine reads from Stdin and delivers that data to the command
        // over a pipe. In this case, Wait does not complete until the goroutine
        // stops copying, either because it has reached the end of Stdin
        // (EOF or a read error) or because writing to the pipe returned an error.
        Stdin io.Reader
    
        // Stdout and Stderr specify the process's standard output and error.
        //
        // If either is nil, Run connects the corresponding file descriptor
        // to the null device (os.DevNull).
        //
        // If either is an *os.File, the corresponding output from the process
        // is connected directly to that file.
        //
        // Otherwise, during the execution of the command a separate goroutine
        // reads from the process over a pipe and delivers that data to the
        // corresponding Writer. In this case, Wait does not complete until the
        // goroutine reaches EOF or encounters an error.
        //
        // If Stdout and Stderr are the same writer, and have a type that can
        // be compared with ==, at most one goroutine at a time will call Write.
        Stdout io.Writer
        Stderr io.Writer

    示例

    /*
    参数传入的是命令组
    通过buffer一次次读取返回结果,不怕返回的数据量大
    如果命令是shell那样有|管道符,则使用Pip方法即可
     */
    func PipCmd(cmd []string,useBufferIO... bool) string {
        useBufferedIO := false
    
        ll := len(useBufferIO)
        if ll > 0 {
            useBufferedIO = useBufferIO[0]
        }
        cmd0 := Command(cmd)
        stdout0, err := cmd0.StdoutPipe()
        if err != nil {
            fmt.Printf("Error: Couldn't obtain the stdout pipe for command : %s
    ", err)
            return ""
        }
        defer stdout0.Close()
        if err := cmd0.Start(); err != nil {
            fmt.Printf("Error: The command  can not be startup: %s
    ", err)
            return ""
        }
        if !useBufferedIO {
            var outputBuf0 bytes.Buffer
            for {
                tempOutput := make([]byte, 1024)
                n, err := stdout0.Read(tempOutput)
                if err != nil {
                    if err == io.EOF {
                        break
                    } else {
                        fmt.Printf("Error: Couldn't read data from the pipe: %s
    ", err)
                        return ""
                    }
                }
                if n > 0 {
                    outputBuf0.Write(tempOutput[:n])
                }
            }
            //fmt.Printf("%s
    ", outputBuf0.String())
            res := fmt.Sprintf("%v",outputBuf0.String())
            return res
        } else {
            outputBuf0 := bufio.NewReader(stdout0)
            var resBuffer bytes.Buffer
    
            for{
                //outputBuf0 默认带一个4K的缓冲区,第二个参数为false表示读取完所有的行
                output0, _, err := outputBuf0.ReadLine()
    
                if err != nil {
                    if err == io.EOF{
                        break
                    }
                    fmt.Printf("Error: Couldn't read data from the pipe: %s
    ", err)
                    return ""
                }
                output0 = append(output0,'
    ')
                resBuffer.Write(output0)
            }
            res := fmt.Sprintf("%v",resBuffer.String())
            return res
        }
    }
    
    
    func Command(cmds []string) *exec.Cmd {
        name:= cmds[0]
        cmd := &exec.Cmd{
            Path: name,
            Args: cmds,
        }
    
        if filepath.Base(name) == name {
            if lp, err := exec.LookPath(name); err != nil {
                //cmd.lookPathErr = err
                ErrorHandle(err)
            } else {
                cmd.Path = lp
            }
        }
        return cmd
    }
    func a11()  {
        //命令行参数不能包含空格,比如-ht 是错的,-ht是对的
        cmd := []string{"/opt/wks/go/dbm_go/src/dbm/consistency/consis_0.6.7", "-cht",  "192.168.177.67", "-cpt", "3316", "-ht","114.67.105.113,192.168.177.67", "-pt","3306,3316", "-slot",  "-json", "-db", "vodb", "-timeStart", "2020-09-11 14:09:27", "-pl", "2"}
        res := tools.PipCmd(cmd,true)
        fmt.Println(res)
    }
  • 相关阅读:
    matlab中fft与fftshift命令小结(转)
    matlab 添加多行注释
    matlab colormap,caxis,shading,hsv,pcolor, alpha 表示(转)
    在线latex公式编辑器
    matlab 对话框弹出
    步态识别 概要
    JavaScript函数
    MySQL多表查询总结
    VS2005打不开 卡在登入状态
    about project
  • 原文地址:https://www.cnblogs.com/perfei/p/13563289.html
Copyright © 2020-2023  润新知