sh/bash/dash/ksh/zsh等Shell脚本
-
jiandan23
- 帖子: 86
- 注册时间: 2010-12-17 22:31
- 系统: Mint 19.2
#1
帖子
由 jiandan23 » 2023-09-19 16:30
各位好,最近在看《UNIX环境高级编程》关于终端的两章时,遇到一点问题,希望懂的人帮忙看下!
关于终端的回显,按照书里的意思,当回显开启后,用户输入的内容会自动回显到终端上面,且这个功能是由终端自己实现的,和bash无关。我的问题如下:
- 在bash命令提示符后面输入命令,每敲入一个字符,终端上便会输出一个字符。这个机制是通过“终端回显”实现的吗?
- 如果是,为什么将bash的stderr重定向到/dev/null之后(bash下执行“exec 2>/dev/null”),输入命令不再有回显了?
关于TERM变量:ssh登录某台linux主机,$TERM的值是xterm,这个xterm和/usr/bin/xterm是啥关系?
谢谢!!
-
astolia
- 论坛版主
- 帖子: 6494
- 注册时间: 2008-09-18 13:11
#2
帖子
由 astolia » 2023-09-20 16:01
jiandan23 写了: ↑2023-09-19 16:30
且这个功能是由终端自己实现的,和bash无关
这个说法不太准确。回显与否可以看作是终端的一个选项。bash默认是通过readline库来读取用户的输入,在readline库内部会去查询这个选项,如果没有禁止回显,则会将用户的输入再输出到指定的输出流中,就实现了回显这一功能。这个过程是发生在bash进程内的,说和bash无关也不合适
jiandan23 写了: ↑2023-09-19 16:30
如果是,为什么将bash的stderr重定向到/dev/null之后(bash下执行“exec 2>/dev/null”),输入命令不再有回显了?
因为bash在初始化readline库时,将readline的输出流设置成了stderr(见bash源码
https://git.savannah.gnu.org/cgit/bash. ... h-5.2#n459 ),所以所有由readline输出的内容,包括回显文字以及提示符,都被重定向到了/dev/null
以上都是基于bash用readline库这一前提。如果在编译bash时禁用了readline库,那么即使你执行了exec 2>/dev/null,回显也不受影响
jiandan23 写了: ↑2023-09-19 16:30
关于TERM变量:ssh登录某台linux主机,$TERM的值是xterm,这个xterm和/usr/bin/xterm是啥关系?
TERM环境变量用来说明当前终端拥有的各项能力。设置成xterm,表示用terminfo数据库中xterm项的配置,对应的配置文件是/usr/share/terminfo/x/xterm。这个配置文件来自ncurses库,仅仅是表述了某一版xterm终端模拟器具有的能力,并不依赖xterm
-
jiandan23
- 帖子: 86
- 注册时间: 2010-12-17 22:31
- 系统: Mint 19.2
#3
帖子
由 jiandan23 » 2023-09-22 16:34
astolia 写了: ↑2023-09-20 16:01
jiandan23 写了: ↑2023-09-19 16:30
且这个功能是由终端自己实现的,和bash无关
这个说法不太准确。回显与否可以看作是终端的一个选项。bash默认是通过readline库来读取用户的输入,在readline库内部会去查询这个选项,如果没有禁止回显,则会将用户的输入再输出到指定的输出流中,就实现了回显这一功能。这个过程是发生在bash进程内的,说和bash无关也不合适
jiandan23 写了: ↑2023-09-19 16:30
如果是,为什么将bash的stderr重定向到/dev/null之后(bash下执行“exec 2>/dev/null”),输入命令不再有回显了?
因为bash在初始化readline库时,将readline的输出流设置成了stderr(见bash源码
https://git.savannah.gnu.org/cgit/bash. ... h-5.2#n459 ),所以所有由readline输出的内容,包括回显文字以及提示符,都被重定向到了/dev/null
以上都是基于bash用readline库这一前提。如果在编译bash时禁用了readline库,那么即使你执行了exec 2>/dev/null,回显也不受影响
多谢解答!
我用strace跟踪了下,确实在命令提示符后面的回显,是由bash进程写到终端的。
同时在bash源码中也找到了“rl_outstream = stderr;”,所以重定向stderr到/dev/null,会导致输入命令回显不可见,这个可以理解。
但我进一步测试,发现了以下问题:(为了描述方便,我把上面这种回显暂且称之为“readline回显”)
在执行“exec 2>/dev/null”之后(此时敲入命令已经不再有回显),然后运行sleep 10m,在sleep阻塞时,再敲入字符,又有回显了,如下:
代码: 全选
[root@host ~]# exec 2>/dev/null
#敲入命令“sleep 10m”,无回显
#在sleep运行时,敲入"hello",有回显
hello
这种回显是由终端的"line discipline"带来的吗?
前面提到的"readline回显"是不是会覆盖这种回显?不然bash命令提示符后面输入的命令,就要被回显两边了。
谢谢!