下面片段中的关键语句(即除了用于打印标签和空白行的那些,用于间距)成对出现。在每一对中,第一个和第二个语句的形式分别为tty...
和。echo $(tty...)
echo stdin:
tty
echo $(tty)
echo
echo stdout:
tty <&1
echo $(tty <&1)
echo
echo stderr:
tty <&2
echo $(tty <&2)
如果我获取包含此片段的文件(例如,在一个zsh
或bash
会话中),我会得到以下输出1(我随后添加了行号,以供参考):
1 stdin:
2 /dev/pts/8
3 /dev/pts/8
4
5 stdout:
6 /dev/pts/8
7 not a tty
8
9 stderr:
10 /dev/pts/8
11 /dev/pts/8
在此输出中,由echo $(tty <&1)
(第 7 行)生成的行显着突出,原因有两个:
- 它是- 生成的
echo $(tty ...)
行(即,第 3、7 和 11 行)中唯一与其tty ...
前面的 - 生成的对应物(第 2、6 和 10 行)不同的行;和 - 它不同于形式上类似的输出(第 11 行)
echo $(tty <&2)
。
问:如何解释这两个差异?
作为记录,我试图在 的手册页中找到这些明显异常的解释tty
,但是,据我所知,该页面根本没有解决这些问题2;当然不是明确的3。
这个问题是由一些代码激发的,这是我早期问题的一个很好的答案。
1当然,/dev/pts/
如果我更换终端后实际数字会有所不同,如果您尝试相同的事情,您可能会有所不同。
2事实上,tty
我系统上可用的手册页的整个说明部分仅包含一句话:“打印连接到标准输入的终端的文件名。”。
3在这里,我保留一个可能性,即比我拥有更多背景知识的人可能能够从's 简洁的手册页中推断tty
出上述行为。
tty
报告(在其标准输出上)在其标准输入(其 fd 0)上打开的 tty 设备的名称。在:
简称
shell 将 fd 0 重定向到与 fd 2 上打开的资源相同的资源(
dup2(2, 0)
在新进程中执行 a 然后tty
在该进程中运行。因此tty
在其 fd 0 和 2 上将具有相同的资源并在 fd 1 上写入 tty 即两者都打开(如果有)。同样的情况发生在:
在:
但是,该命令替换的 fd 1 进入管道(并且 shell 读取
tty
另一端的输出),它与 fd 1echo
进入的资源不同。如果您想知道 fd 1 上打开了什么 tty 并使用命令替换,您需要类似以下内容:
所以对于正在运行的进程
tty
,我们有:因此可以将连接到外部
tty
标准输出的 tty 设备的路径写入该管道。由于 tty 不需要那个 fd 3,你可以让它更干净一点:
也就是说,在你使用它复制到 fd 0 之后关闭它。