打开xterm
,运行tty
并查看伪终端从属文件(假设它是/dev/pts/0
)。然后打开另一个xterm
并运行
$ stty -F /dev/pts/0
speed 38400 baud; line = 0;
lnext = <undef>; discard = <undef>; min = 1; time = 0;
-brkint -icrnl -imaxbel iutf8
-icanon -echo
/bin/sleep 1000
然后先在xterm中运行。然后stty
在第二个 xterm 中再次运行相同的命令:
$ stty -F /dev/pts/0
speed 38400 baud; line = 0;
-brkint -imaxbel iutf8
然后终止sleep
第一个 xterm 中的命令。然后stty
在第二个 xterm 中再次运行相同的命令:
$ stty -F /dev/pts/0
speed 38400 baud; line = 0;
lnext = <undef>; discard = <undef>; min = 1; time = 0;
-brkint -icrnl -imaxbel iutf8
-icanon -echo
我们看到 bash 在运行命令之前更改了 tty 属性,并在运行命令之后恢复它们。 bash 文档中哪里描述了它?是否所有tty属性都恢复了,或者如果通过程序更改了某些属性可能无法恢复?
答案1
这就是readline(3)
行编辑库,通常作为 bash 的一部分静态构建,但也被其他程序使用。
每次开始读取用户的命令时,readline 都会保存终端设置,并将终端置于“原始”模式 [1],因此它能够处理左右移动插入点、从历史记录中调用命令当readline(3)
返回时(例如,当用户按下 Enter 时),终端的原始设置被恢复。 Readline 也会扰乱信号,这可能会导致一些令人费解的行为。
如果您进行 strace bash
,请查找ioctl(TCSETS*)
(whichimplements tcsetattr(3)
) 和ioctl(TCGETS)
( tcgetattr(3)
)。这些与stty(1)
.如果您运行 bash,--noediting
您会发现它保留了终端设置。
[1] 不完全是“原始”模式cfmakeraw(3)
;你可以看到具体的细节这里。所有这些终端设置都记录在termios(3)
联机帮助页中。