当 stdin 是别的东西时,Go 程序可以从键盘读取吗?
Can a Go program read from the keyboard when stdin is something else?
我有一个通过管道接受输入的 Go 进程。
tail -f something.foo | go run myprog.go
由于 stdin 是管道的输出,我在 myprog.go 中找不到读取键盘输入的方法。这可能吗?
我考虑过在 myprog.go 中执行 tail 命令,但我想避免在 myprog.go 崩溃并且无法终止另一个进程的情况下创建另一个进程。
在 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
您可以使用 shell 创建一个管道来为您的程序提供输入,同时让 stdin 空闲用于其他事情。听起来有点像
go run myprog.go <(tail -f something.foo)
shell 将执行 tail
并将其标准输出重定向到新的 fifo。您的程序接收 fifo 作为第一个参数,指向 /proc/self/fd/1234567
我有一个通过管道接受输入的 Go 进程。
tail -f something.foo | go run myprog.go
由于 stdin 是管道的输出,我在 myprog.go 中找不到读取键盘输入的方法。这可能吗?
我考虑过在 myprog.go 中执行 tail 命令,但我想避免在 myprog.go 崩溃并且无法终止另一个进程的情况下创建另一个进程。
在 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
您可以使用 shell 创建一个管道来为您的程序提供输入,同时让 stdin 空闲用于其他事情。听起来有点像
go run myprog.go <(tail -f something.foo)
shell 将执行 tail
并将其标准输出重定向到新的 fifo。您的程序接收 fifo 作为第一个参数,指向 /proc/self/fd/1234567