gpt4 book ai didi

go - 具有修改后的Stdin的exec.Wait()无限期等待

转载 作者:行者123 更新时间:2023-12-01 22:07:18 27 4
gpt4 key购买 nike

我在使用经过修改的Stdin的exec.Wait()时遇到奇怪的行为。
我只是在修改Stdin,以便能够复制其内容,计算数据量……但这不是问题所在。

我制作了这个精简的程序只是为了演示奇怪的行为:

带有经过修改的Stdin的

  • cmd.Wait()无限期等待……直到我按下“enter”或“^ C”
  • 带有未修改的Stdin的
  • (取消注释cmd.Stdin = os.Stdin行),程序可以完美地进行处理。
  • 当我使用Delve(dlv debug)启动此程序(带有经过修改的Stdin)时,该程序会完美地运行到最后!
  • 我还在time.Sleepcmd.Start()之间添加了一个30秒的cmd.Wait(),然后将该程序附加到Delve(dlv attach PID)。当我输入continue时,cmd.Wait()会无限期地等待……直到我按下“enter”或“^ C”

  • 我用go1.11和go1.12测试了这些行为
    package main

    import (
    "fmt"
    "os"
    "os/exec"
    )

    type Splitter struct {
    f *os.File
    fd int
    }

    func NewSplitter(f *os.File) *Splitter {
    return &Splitter{f, int(f.Fd())}
    }

    func (s *Splitter) Close() error {
    return s.f.Close()
    }

    func (s *Splitter) Read(p []byte) (int, error) {
    return s.f.Read(p)
    }

    func (s *Splitter) Write(p []byte) (int, error) {
    return s.f.Write(p)
    }

    func main() {
    var cmd *exec.Cmd
    cmd = exec.Command("cat", "foobarfile")
    cmd.Stdin = NewSplitter(os.Stdin)
    //cmd.Stdin = os.Stdin
    cmd.Stdout = NewSplitter(os.Stdout)
    cmd.Stderr = NewSplitter(os.Stderr)
    cmd.Start()
    cmd.Wait()
    fmt.Println("done")
    }

    我在做错什么吗?

    谢谢你的帮助。

    最佳答案

    该程序按照您的要求复制内容。您也可以尝试评论的部分。这些评论是不言自明的,我希望它能解释您的查询。

    package main

    import (
    "io"
    "log"
    "os"
    "os/exec"
    )

    func main() {
    // Execute cat command w/ arguments
    // cmd := exec.Command("cat", "hello.txt")

    // Execute cat command w/o arguments
    cmd := exec.Command("cat")

    // Attach STDOUT stream
    stdout, err := cmd.StdoutPipe()
    if err != nil {
    log.Println(err)
    }

    // Attach STDIN stream
    stdin, err := cmd.StdinPipe()
    if err != nil {
    log.Println(err)
    }

    // Attach STDERR stream
    stderr, err := cmd.StderrPipe()
    if err != nil {
    log.Println(err)
    }

    // Spawn go-routine to copy os's stdin to command's stdin
    go io.Copy(stdin, os.Stdin)

    // Spawn go-routine to copy command's stdout to os's stdout
    go io.Copy(os.Stdout, stdout)

    // Spawn go-routine to copy command's stderr to os's stderr
    go io.Copy(os.Stderr, stderr)

    // Run() under the hood calls Start() and Wait()
    cmd.Run()

    // Note: The PIPES above will be closed automatically after Wait sees the command exit.
    // A caller need only call Close to force the pipe to close sooner.
    log.Println("Command complete")
    }

    关于go - 具有修改后的Stdin的exec.Wait()无限期等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60640083/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com