【问题标题】:cmd.ExtraFiles fails when trying to pipe to itcmd.ExtraFiles 尝试通过管道传输时失败
【发布时间】:2019-01-29 01:47:55
【问题描述】:

我正在尝试让管道转到cmd.ExtraFiles

我目前有错误提示

cannot use cmdstdout (type io.ReadCloser) as type []byte in argument to pipeR.Read
cannot use cmdstdout (type io.ReadCloser) as type []byte in argument to fd3.Write

这是我目前的gocode

cmd2 = exec.Command("-i", "pipe:0", "-i", "pipe:1")
cmd1 := exec.Command("command", "-o", "-")
pipeR, pipeW, _ := os.Pipe()
cmd2.ExtraFiles = []*os.File{
    pipeW,
}
cmd1.Start()
cmd1stdout, err := cmd1.StdoutPipe()
if err != nil {
    log.Printf("pipeThruError: %v\n", err)
    return err
}
fd3 := os.NewFile(3, "/proc/self/fd/3")
fd3.Write(cmd1stdout)
pipeR.Read(cmd1stdout)
pipeR.Close()
pipeW.Close()
fd3.Close()
cmd3 = exec.Command("command", "-o", "-")
stdin, stdinErr := cmd3.StdoutPipe()
if stdinErr != nil {
    log.Printf("pipeThruFStdinErr: %v\n", stdinErr)
    return stdinErr
}
cmd3.Start()
cmd2.Stdin = stdin

编辑:添加完整范围 目标是让 cmd2 接受 Stdin 通过 cmd3 的输入,并让 cmd1 输出通过ExtraFiles 进行管道传输

【问题讨论】:

    标签: go pipe


    【解决方案1】:

    这里的类型并不完全一致。具体来说,

    cmd.StdoutPipe
    

    返回一个io.ReadCloser

    pipeR.Read
    

    期待[]byte 作为输入。

    我相信您最终希望利用os packageReadWrite 函数来完成您的任务,如下所示:

    package main
    
    import (
        "log"
        "os"
        "os/exec"
    )
    
    func main() {
        cmd := exec.Command("command", "-o", "-")
        pipeR, pipeW, _ := os.Pipe()
        cmd.ExtraFiles = []*os.File{
            pipeW,
        }
        cmd.Start()
        cmdstdout, err := cmd.StdoutPipe()
        if err != nil {
            log.Printf("pipeThruError: %v\n", err)
            os.Exit(1)
        }
    
        buf := make([]byte, 100)
        cmdstdout.Read(buf)
    
        pipeR.Close()
        pipeW.Close()
        fd3 := os.NewFile(3, "/proc/self/fd/3")
        fd3.Write(buf)
        fd3.Close()
    

    }

    【讨论】:

    • 所以它可以编译,但是当我运行它时 cmd2 看不到输入
    • 考虑到管道的工作方式,这是有道理的。从pipeR 读取返回写入pipeW 的字节。换句话说,我们应该在pipeW
    • 对,但这就是我感到困惑的地方,我试图在原始问题中使用 fd3.Write(cmdstdout) 来做到这一点
    • 我认为这应该可行,只是你必须在读取之前进行写入,然后利用读取来获取数据。
    • 我继续更新问题,尝试在读取之前写入,以及更好地命名变量,但它仍然找不到流
    猜你喜欢
    • 2020-05-07
    • 1970-01-01
    • 2021-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-08
    • 1970-01-01
    • 2013-08-15
    相关资源
    最近更新 更多