学习中TLDP 的高级 Bash 脚本编写指南我无法在 debian 9 的 bash 4.4.12 中从 tty 和 pts 重建以下 shell 输出:
bash$ lsof -a -p $$ -d0,1,2
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
bash 363 bozo 0u CHR 136,1 3 /dev/pts/1
bash 363 bozo 1u CHR 136,1 3 /dev/pts/1
bash 363 bozo 2u CHR 136,1 3 /dev/pts/1
bash$ exec 2> /dev/null
bash$ lsof -a -p $$ -d0,1,2
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
bash 371 bozo 0u CHR 136,1 3 /dev/pts/1
bash 371 bozo 1u CHR 136,1 3 /dev/pts/1
bash 371 bozo 2w CHR 1,3 120 /dev/null
每当我运行第二个命令时,shell 提示符就会消失,所有键盘输入都会停止显示,但我仍然可以运行命令并查看其输出。这是为什么?
答案1
这是因为您已经重定向了 shell 的标准错误。
根据标准,符合 POSIX 的 shell 应该在此处编写交互式提示。
这谍影重重,传家宝伯恩, (德班和自由BSD)93 科恩,MirBSD 科恩, (自由BSD、OpenBSD 和德班)PD科恩,(自由BSD和德班)阿尔姆奎斯特,和渡边shell 都符合这一点,并将其交互式提示写入标准错误。你会发现他们所有人都缺乏及时的行为。
然而,不回显输入行为要复杂得多:
- Debian PD Korn、Debian Almquist 和 Heirloom Bourne shell 没有实现自己的行编辑器,而是依赖于内核中终端行规则提供的行编辑器。您仍然会看到回显您输入的内容作为其标准输入。
- Watanabe、(FreeBSD 93) Korn 和 (Debian 93) Korn shell 实现了自己的行编辑器,还当它们(重新)显示正在编辑的输入行时,写入标准错误。然而,它们将终端回显在在执行
exec
命令之前,并且(因为标准错误不再是终端设备)再次关闭失败当调用行编辑器进行下一个输入时。因此,您将看到您键入的进一步输入由终端行规则回显,即使来自 shell 行编辑器的输入回显将转到现在重定向的标准错误。他们的行编辑器也会以微妙的方式出现错误,例如无法识别任何进一步的终端尺寸变化。 - MirBSD Korn、(FreeBSD PD) Korn 和 (OpenBSD PD) Korn shell 实现自己的行编辑器,这些编辑器(重新)将编辑的行显示到标准错误,但
/dev/tty
直接打开另一个文件描述符以控制终端回显等内容。他们成功在调用行编辑器进行下一个输入时再次关闭回显。这样你就会不是查看您键入的行编辑器回显的进一步输入或者终端线路纪律。 - Bourne Again 和 FreeBSD Almquist shell 实现了自己的行编辑器,可以(重新)将编辑后的行显示为标准错误,但使用标准输入控制诸如终端回声之类的东西。他们成功在调用行编辑器进行下一个输入时再次关闭回显。这样你就会不是查看您键入的行编辑器回显的进一步输入或者终端线路纪律。
这BusyBox阿尔姆奎斯特和Zshell 在这方面不符合 POSIX。他们都实现了自己的行编辑器。有了这两者,您就会看到该附录让您相信将会发生的行为。
- BusyBox Almquist shell 的行编辑器使用标准输出来输入回显,即还它写提示的地方。它根本不受标准错误重定向的影响。但您可以通过重定向标准输出来获得效果。它使用标准输入来识别终端尺寸的变化。
- Z shell 会付出一些努力来尝试找到一个终端设备来运行 ZLE,直到并包括显式打开
/dev/tty
.它在启动时将文件描述符复制到终端设备,然后 ZLE 将其用于一切;用于回显键入的输入,用于阅读键入的输入,用于编写交互式提示以及打开和关闭终端回显。因此,ZLE 不受标准错误、输出甚至输入的后续重定向的影响。如果您愿意,您可以将所有三个重定向到/dev/null
byexec
,并且 Z shell 仍会以交互方式提示您并接收输入。
(这汤普森exec
shell首先不支持 shell命令机制,因为它早于它的发明。)
您应该向作者 Stéphane Chazelas 抱怨该附录是错误的,以便它可以得到修复。
进一步阅读
- ”外壳变量”。 壳牌和公用事业公司。基本规格。 IEEE 1003.1:2017。开放组。 2017年。
- https://unix.stackexchange.com/a/299440/5132