我正在尝试在Bash脚本中使用tput
,并尽力避免随机错误。为此,我写了以下这一行:
COLS="$(tput cols 2> /dev/null)"
令我惊讶的是,当我运行它时,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
因此,tput
似乎成功地在重定向stderr时确定终端特性,或者当它嵌入在进程替换中时,但不是两者都有。多奇怪啊!
我在Linux和OS X上测试了这个,行为是一样的。
这里发生了什么?实际上,在抑制stderr喷射的同时让tput
工作的最佳方法是什么?
注意:我知道$COLUMNS
。我特别感兴趣的是使用tput
。
答案 0 :(得分:5)
快速strace
运行表明tput
首先尝试确定stdout
上的终端宽度,如果失败,则会回退到stderr
。因此,在失败的情况下,两者都被重定向,并且tput
(显然)假设默认值为80列。
答案 1 :(得分:0)
我的具体情况是编写可以从命令行或从cron调用的脚本。从cron运行时,Solaris将TERM
变量设置为" dumb",tput
对此一无所知,并且它会发出错误(将邮件发送给所有者的cron工作)。由于您无法捕获错误并且stdout要获取列数,因此我首先尝试找出一种方法来确定tput是否知道特定终端,然后再运行tput cols
。为此,这段代码似乎符合我的目的:
declare TPUT C
TPUT="$(tput longname 2>/dev/null)"
[[ "$TPUT" ]] && C="$(tput cols)"
C=${C:-80}
我意识到这并没有抓住所有错误,但如果tput
不了解某个特定终端,它至少可以避免错误。