我正在尝试在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上都测试了这一点,行为也是一样的。
这里发生什么事情?作为一个实际问题,在抑制stderr的同时使tput工作的最佳方法是什么?
注:我知道$COLUMNS的事。我对使用tput特别感兴趣。
发布于 2014-02-13 19:41:58
快速的strace运行表明,tput首先尝试确定stdout上的终端宽度,如果失败,则返回到stderr。因此,在失败的情况下,两者都被重定向,而tput (显然)假定默认为80列。
发布于 2015-01-28 22:42:09
谷歌带领我来到这里,因为我有一个类似的问题。虽然公认的答案确实回答了这个问题,但实际上它并没有给出任何关于如何解决最初问题中提到的错误的建议。我想我应该加入到可能的工作中来。
我的具体情况是编写可以从命令行或cron调用的脚本。当从cron运行时,Solaris将TERM变量设置为“哑”( tput不知道这一点),它会产生错误(这些错误会被邮寄给cron作业的所有者)。由于无法捕获错误和标准输出来获取列数,所以在运行tput cols之前,我首先尝试找出一种方法来确定tput是否知道某个特定的终端。为此,这段代码似乎达到了我的目的:
declare TPUT C
TPUT="$(tput longname 2>/dev/null)"
[[ "$TPUT" ]] && C="$(tput cols)"
C=${C:-80}我意识到这并不能捕获所有的错误,但是如果tput不知道一个特定的终端,它至少会避免可能出现的错误。
发布于 2021-11-10 08:24:02
显然,他们在那之后改变了tput。它在Ubuntu18.04中工作得更好(ncurses 6.2.20200212)。即使在较早的软件运行eval $(resize)之前,tput命令也可能有所帮助,但必须为此安装xterm。有关here方法的替代方案,请参阅tput。
https://stackoverflow.com/questions/21763397
复制相似问题