我如何使 stdin 成为 tty?
How do I make stdin a tty?
有些程序会根据其标准输出是否为 tty 来更改其输出。因此,如果将它们放入管道或重定向它们,输出将与 shell 中的输出不同。这是一个例子:
$ touch a b c
# when running ls alone, it places them on one line
$ ls
a b c
# when stdout is not a tty, it places them on their own line
$ ls > output
$ cat output
a
b
c
output
因此,如果我想向某人展示这样的命令应该是什么样子(例如,我正在编写教程),我必须突出显示并复制终端的输出,然后将其保存到文件中。
看来我应该可以做这样的事情:
ls | ttypipe > output
其中 ttypipe
是一个假设程序,其标准输入(以及 ls 的标准输出)在被问及它是否为 tty 时以 true 响应。
我知道在Ruby,我可以做这样的事情:
require 'pty' # => true
IO.pipe.map(&:tty?) # => [false, false]
PTY.open.map(&:tty?) # => [true, true]
但那是针对子进程,而不是当前进程,因此:
$stdin.tty? # => false
我可以执行,但我想不出一种方法来影响标准输入文件描述符。
你不能写ttypipe
因为管道就是管道,永远不可能是tty。但是,您可以使用稍微不同的语法编写 ttyexec
:
ttyexec ls > output
它会打开一个伪终端,运行 ls
在其中,然后将 ls
写入终端的所有内容复制到 ttyexec
的标准输出。
瞧,已经有这样的工具了:script
。它在一个新的、隐藏的 pty 中打开一个程序来记录与它的交互,但我们可以忽略日志记录部分,只使用它的终端打开属性:
$ touch a b c
$ ls
a b c
$ script -q -c 'ls' /dev/null > output
$ cat output
a b c output
有些程序会根据其标准输出是否为 tty 来更改其输出。因此,如果将它们放入管道或重定向它们,输出将与 shell 中的输出不同。这是一个例子:
$ touch a b c
# when running ls alone, it places them on one line
$ ls
a b c
# when stdout is not a tty, it places them on their own line
$ ls > output
$ cat output
a
b
c
output
因此,如果我想向某人展示这样的命令应该是什么样子(例如,我正在编写教程),我必须突出显示并复制终端的输出,然后将其保存到文件中。
看来我应该可以做这样的事情:
ls | ttypipe > output
其中 ttypipe
是一个假设程序,其标准输入(以及 ls 的标准输出)在被问及它是否为 tty 时以 true 响应。
我知道在Ruby,我可以做这样的事情:
require 'pty' # => true
IO.pipe.map(&:tty?) # => [false, false]
PTY.open.map(&:tty?) # => [true, true]
但那是针对子进程,而不是当前进程,因此:
$stdin.tty? # => false
我可以执行,但我想不出一种方法来影响标准输入文件描述符。
你不能写ttypipe
因为管道就是管道,永远不可能是tty。但是,您可以使用稍微不同的语法编写 ttyexec
:
ttyexec ls > output
它会打开一个伪终端,运行 ls
在其中,然后将 ls
写入终端的所有内容复制到 ttyexec
的标准输出。
瞧,已经有这样的工具了:script
。它在一个新的、隐藏的 pty 中打开一个程序来记录与它的交互,但我们可以忽略日志记录部分,只使用它的终端打开属性:
$ touch a b c
$ ls
a b c
$ script -q -c 'ls' /dev/null > output
$ cat output
a b c output