当stdin是别的什么时,可以从键盘读取Go程序吗?

时间:2015-04-02 17:25:10

标签: go pipe stdin

我有一个Go流程,通过管道接受输入。

  

tail -f something.foo |去运行myprog.go

由于stdin是管道的输出,我找不到在myprog.go中读取键盘输入的方法。这可能吗?

我考虑在myprog.go中执行tail命令,但是我想避免在myprog.go崩溃的情况下创建另一个进程并且无法终止另一个进程。

2 个答案:

答案 0 :(得分:5)

在linux(以及一般POSIX)上,您可以打开/dev/tty以获取进程控制tty的输入。

func readStdin() {
    buf := make([]byte, 1024)
    for {
        n, err := os.Stdin.Read(buf)
        if err != nil && err != io.EOF {
            log.Fatal(err)
        }
        fmt.Print("FROM STDIN:", string(buf[:n]))
        if err == io.EOF {
            return
        }
    }
}

func main() {
    go readStdin()

    buf := make([]byte, 1024)
    tty, err := os.Open("/dev/tty")
    if err != nil {
        log.Fatal(err)
    }
    defer tty.Close()
    for {
        n, err := tty.Read(buf)
        if err != nil && err != io.EOF {
            log.Fatal(err)
        }
        fmt.Print("FROM TTY:", string(buf[:n]))
        if err == io.EOF {
            return
        }
    }
}

哪个可以输出:

$ echo HELLO | ./tty_reader
FROM STDIN:HELLO
typing on my keyboard
FROM TTY:typing on my keyboard

答案 1 :(得分:-1)

您可以使用shell创建一个管道,以便为您的程序提供输入,同时让stdin免费用于其他事情。

的声音
go run myprog.go <(tail -f something.foo)

shell将执行tail并将其stdout重定向到新的fifo。你的程序收到fifo作为第一个参数,指向/proc/self/fd/1234567