好奇的tput行为,带有stderr重定向

dan*_*uzz 6 bash io-redirection

我正在尝试使用tputBash脚本,并尽力避免随机错误喷出.为此,我写了以下这一行:

COLS="$(tput cols 2> /dev/null)"
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,当我运行它时,无论我的终端窗口的宽度是多少,COLS都始终设置为80.(为了演示,我的终端恰好是115列宽.)为了弄清楚发生了什么,我在命令行上尝试了一些事情:

$ tput cols
115
$ tput cols | cat
115
$ echo "$(tput cols)"
115
$ tput cols 2> /dev/null
115
$ echo "$(tput cols 2> /dev/null)"
80
Run Code Online (Sandbox Code Playgroud)

因此,tput当它的stderr被重定向时,或者当它被嵌入到进程替换中时,似乎成功地找出终端特性,但不是两者都有.多奇怪啊!

我在Linux和OS X上测试了这个,行为是一样的.

这里发生了什么?而作为一个实际问题,tput在抑制stderr喷射的同时,最好的工作方式是什么?

注意:我知道$COLUMNS.我特别感兴趣的是使用tput.

use*_*058 5

快速strace运行表明首先tput尝试确定终端宽度stdout,如果失败,则回退到stderr.因此,在失败的情况下,两者都被重定向,并且tput(显然)假设默认为80列.