在输出量上转义序列是否有客观好处?


11

.*rc网上的人们的档案或各种代码中,我倾向于看到许多人手动使用ANSI转义序列而不是使用tput

我的理解tput是更通用/更安全,所以这使我感到奇怪:

是否有任何客观原因应该使用转义序列代替tput?(可移植性,错误的鲁棒性,异常的终端...?)


在可移植性问题的另一面,MobaXterm可与printfANSI转义序列一起使用,但会tput失败(至少在我的盒子上)。
通配符

Answers:


6

tput可以处理典型的shell脚本发现不可用的表达式(例如in sgrsetaf)。要了解所涉及的内容,请查看应用infocmp-f(格式)选项的输出。这是使用xterm的terminfo描述中的那些字符串的示例之一:

xterm-16color|xterm with 16 colors,
        colors#16,
        pairs#256,
        setab=\E[
                %?
                        %p1%{8}%<
                        %t%p1%{40}%+
                %e
                        %p1%{92}%+
                %;%dm,
        setaf=\E[
                %?
                        %p1%{8}%<
                        %t%p1%{30}%+
                %e
                        %p1%{82}%+
                %;%dm,
        setb=
                %p1%{8}%/%{6}%*%{4}%+\E[%d%p1%{8}%m%Pa
                %?%ga%{1}%=
                        %t4
                %e%ga%{3}%=
                        %t6
                %e%ga%{4}%=
                        %t1
                %e%ga%{6}%=
                        %t3
                %e%ga%d
                %;
                m,
        setf=
                %p1%{8}%/%{6}%*%{3}%+\E[%d%p1%{8}%m%Pa
                %?%ga%{1}%=
                        %t4
                %e%ga%{3}%=
                        %t6
                %e%ga%{4}%=
                        %t1
                %e%ga%{6}%=
                        %t3
                %e%ga%d
                %;
                m,
        use=xterm+256color,
        use=xterm-new,

格式化将事情分解了—要执行相同的脚本或程序,必须遵循这些曲折。大多数人放弃并只使用最简单的字符串。

16色功能是从IBM aixterm借来的,该aixterm将前景和背景的16个代码分别映射到两个范围内。

  • 前景进入30-37和90-97
  • 背景到40-47和100-107

一个简单的脚本

#!/bin/sh
TERM=xterm-16color
export TERM
printf '    %12s %12s\n' Foreground Background
for n in $(seq 0 15)
do
    F=$(tput setaf $n | cat -v)
    B=$(tput setab $n | cat -v)
    printf '%2d  %12s %12s\n' $n "$F" "$B"
done

输出显示其工作方式:

      Foreground   Background
 0        ^[[30m       ^[[40m
 1        ^[[31m       ^[[41m
 2        ^[[32m       ^[[42m
 3        ^[[33m       ^[[43m
 4        ^[[34m       ^[[44m
 5        ^[[35m       ^[[45m
 6        ^[[36m       ^[[46m
 7        ^[[37m       ^[[47m
 8        ^[[90m      ^[[100m
 9        ^[[91m      ^[[101m
10        ^[[92m      ^[[102m
11        ^[[93m      ^[[103m
12        ^[[94m      ^[[104m
13        ^[[95m      ^[[105m
14        ^[[96m      ^[[106m
15        ^[[97m      ^[[107m

的号码被分割,因为aixterm中使用30-37和40-47的范围,以匹配ECMA-48(也称为“ANSI”)的颜色,并且使用90-107范围的代码在标准中定义。

这是xterm使用的屏幕截图TERM=xterm-16color,您可以在其中看到效果。

在此处输入图片说明

进一步阅读:


我可能会证明您的观点,但是这些表达方式有什么用?通过查看infocmp手册,我意识到它们是if-then-else语句...但是我从未见过,并且在使用谷歌搜索时遇到了麻烦,是我找到的全部内容,但是我不确定它是这里发生了什么。谢谢!
上尉曼

2

从UNIX平台可以连接各种设备的时代开始,我仍然更喜欢tput及其朋友而不是字面转义序列。

我认为真正的原因是大多数人根本不了解tput其相关的terminfo/ termcap文件和库。


1

原因之一tput是外部命令,因此运行速度可能比内置的外壳转义代码慢。另一件事是,可以轻松地创建一个将ANSI转义码与外壳特定的转义字符结合在一起的衬里,例如在bash提示中:

PS1='\[\033[1;32m\]\u@\h\[\033[1;34m\] \w >\[\033[0m\] '

类似地在zsh

PS1=$'%{\e[1;32m%}%n@%m%{\e[1;34m%} %3~> %{\e[0m%}'

这里的一切都清晰紧凑。使用tput一个将需要将其拆分为多行或使其变得更长且更复杂,执行tput多次,等等。


1
有了tput,您仍然可以做一线客 PS1="$(tput setaf 2)\u@\h$(tput reset) >
Man Captain

2
实际上这将是$(tput sgr0)结局,但是同意tput是一种改进。
Thomas Dickey
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.