关于 `tty

关于 `tty

下面代码片段中的关键语句(即除了用于打印标签和空行、用于间距的语句之外)成对出现。在每一对中,第一个和第二个语句的形式分别为tty...echo $(tty...)

echo stdin:
tty
echo $(tty)

echo

echo stdout:
tty <&1
echo $(tty <&1)

echo

echo stderr:
tty <&2
echo $(tty <&2)

如果我获取包含此代码片段的文件(例如,在zshor会话中),我会得到以下输出1(之后我添加了行号,以供参考):bash

 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

在此输出中,由(第 7 行)生成的行echo $(tty <&1)非常突出,原因有两个:

  1. echo $(tty ...)它是生成的行(即第 3、7 和 11 行)中唯一tty ...与其前面的生成的对应行(第 2、6 和 10 行)不同的行;和
  2. 它与形式上类似的 的输出(第 11 行)不同echo $(tty <&2)

问:这两个差异如何解释?


作为记录,我试图在 的手册页中找到这些明显异常的解释tty,但是,据我所知,该页面根本没有解决这些问题2;当然不是明确的3 .

这个问题是由一些代码引发的这个很好的答案我之前的一个问题。


1当然,/dev/pts/如果我更换终端,之后的实际数字会有所不同,如果你尝试同样的事情,对你来说可能会有所不同。

2事实上,tty我的系统上可用的手册页的整个描述部分仅包含一句话:“打印连接到标准输入的终端的文件名。”。

3在这里,我保留了一种可能性,即比我拥有更多背景知识的人可能能够推断tty的简洁手册页可以看出上面所示的行为。

答案1

tty(在其标准输出上)报告在其标准输入(其 fd 0)上打开的 tty 设备的名称。

在:

tty <&2

这是哪个缩写

tty 0<&2

shell 将 fd 0 重定向到与 fd 2 上打开的相同资源(dup2(2, 0)在新进程中执行 a,然后tty在该进程中运行)。因此,tty其 fd 0 和 2 上将具有相同的资源,并在 fd 1 上写入 tty两者都打开(如果有)。

同样的情况发生在:

tty <&1

在:

echo "$(tty <&1)"

然而,该命令替换的 fd 1 转到管道(并且 shell 读取另一端的输出),它与 fd 1转到的tty资源不同。echo

如果您想知道 fd 1 上打开的 tty 并使用命令替换,您需要类似以下内容:

{ echo "$(tty <&3)"; } 3<&1

因此对于正在运行的进程tty,我们有:

  • 3:与外层1相同
  • 1:一根管子
  • 2:未动过
  • 0:与3相同,因此与外部1相同

因此tty可以将连接到的 tty 设备的路径写入该管道标准输出。

由于 tty 不需要 fd 3,因此您可以使用以下命令使其更简洁:

{ echo "$(tty <&3 3<&-)"; } 3<&1

也就是说,用完后关闭它,将其复制到fd 0。

相关内容