我在 bash 脚本中有一个函数:message_offset
用于打印 bash 脚本的状态。
即您可以将其称为向其中传递消息和状态,如下所示
message_offset "install font library" "[ OK ]"
它将打印到终端,其中printf
的%*s
格式用于始终设置[ OK ]
80 列宽的最右边字符,例如输出将是
install font library [ OK ]
update configuration file on server [ ERR ]
^
|
always
at 80
如果echo
使用输出将如下所示
install font library [ OK ]
update configuration file on server [ ERR ]
代码:
#!/usr/bin/env bash
function message_offset() {
local message="$1"
local status="$2"
# compensate for the message length by reducing the offset
# by the length of the message,
(( offset = 80 - ${#message} ))
# add a $(tput sgr0) to the end to "exit attributes" whether a color was
# set or not
printf "%s%*s%s" "${message}" 80 "$status" "$(tput sgr0)"
}
这一切都正常,直到我尝试使用tput
在字符串中添加一些颜色序列,即使“[ ERR ]”变成红色。
看来printf "%*s"
格式化是在设置偏移量时计算 tput 字符序列,所以如果我像这样调用函数
message_offset "update configuration file on server" "$(tput setaf 1)[ ERR ]"
输出将类似于:
install font library [ OK ]
update configuration file on server [ ERR ]
因为printf "%*s"
是说嘿这个字符串已经得到了所有"[ ERR ]"
字符,加上"$(tput setaf 1)
字符,但显然"$(tput setaf 1)
字符没有被打印,所以实际上不会影响填充。
有没有办法为“状态”消息添加颜色,并使用tput
样式颜色序列?
答案1
你让事情变得比应有的复杂得多。您可以处理对齐$message
而不关心 ANSI 序列的宽度:
#! /usr/bin/env bash
message() {
[ x"$2" = xOK ] && color=2 || color=1
let offset=$(tput cols)-4-${#2}
printf "%-*s[ %s%s%s ]\n" $offset "$1" "$(tput setaf "$color")" "$2" "$(tput sgr0)"
}
message "install font library" "OK"
message "update configuration file on server" "ERR"
编辑:请注意,大多数printf(1)
实现不能很好地处理多字节字符集的长度计算。因此,如果您想以 UTF-8 格式打印带有重音字符的消息,您可能需要采用不同的方法。耸肩
答案2
一个简单的方法是给所有东西着色后它已经对齐了
简而言之,您需要
一个函数(或者更好的外部脚本)用颜色对字符串进行着色(例如使用 perl 的
s,$regex,$color$&$resetcolor,gi
你称之为后你打印了。颜色转义代码不会以这种方式改变对齐方式。
例如:假设您创建了一个名为“colorize”的脚本,该脚本采用颜色参数,后跟要使用该颜色着色的正则表达式:例如,colorize -blue 'regex1' -green 'regex2'
您在需要时调用它:
{ code
that
formats and display things
} | colorize -red 'ERR' -green 'OK'
将其本身作为脚本允许您在任何地方使用它,例如:
df -h | colorize -red '[890].%'