我正在编写一个脚本,发现了一些奇怪的行为。我确信第 4行和第 6行命令行的输出与其他情况不同是有逻辑解释的,但我找不到它。
1 $ tput cols
128
2 $ tput cols 2>/dev/null
128
3 $ echo $(tput cols)
128
4 $ echo $(tput cols 2>/dev/null)
80
5 $ (tput cols >/tmp/cols.txt); cat /tmp/cols.txt
128
6 $ (tput cols &>/tmp/cols.txt); cat /tmp/cols.txt
80
7 $ echo $(tput cols 2>/dev/null; echo $COLUMNS; tput cols)
80 128 128
为什么 stderr 重定向会改变子 shell 中 tput 的输出?
最终,我想在我的脚本中做这样的事情,以使其在没有 tput/ncurses 的系统上工作:
cols=$(tput cols 2>/dev/null || echo $COLUMNS)
上述示例是使用 Bash 4.3.46(1)-release 和 ncurses 6.0.20150627 创建的
答案1
根据strace
,发生这种情况是因为tput
仅尝试从其 stdout 和 stderr (fd 1 & 2) 读取 tty 设置。由于您已明确重定向 stderr,并且$( )
也重定向 stdout,因此 tput 放弃。
最好的解决办法是修补 tput 以检查标准输入是否存在 tty;但是,您也可以删除2>/dev/null
重定向,因为它tput cols
无论如何都不会输出任何错误消息。(如果它确实输出了一些错误消息,最好注意它们。)