我有一个 ksh 脚本,必须在 linux 和 solaris 上运行。我正在尝试对特定命令的输出进行着色。它可以在 Linux(特别是 RHEL6)上运行,但不能在Solaris(SunOS 5.10)上运行。
Linux 上的命令(输出“test”正确地显示为红色):
[amartin@linuxbox:~]$ echo "test" | sed 's,.*,\x1B[31m&\x1B[0m,'
test
Solaris 上的命令(输出“test”未着色):
[amartin@sunbox:~]$ echo "test" | sed 's,.*,\x1B[31m&\x1B[0m,'
x1B[31mtestx1B[0m
有没有办法制作这个命令,使输出为红色,而输出中没有原始代码?我无法更改“echo”命令,因为这只是我实际运行的命令的填充。
答案1
\xNN
是 GNU sed 中的转义序列,但它不是标准的,特别是它在 Solaris 上不可用。
您可以在脚本中包含字面转义字符,但这会使阅读和编辑变得困难。
您可以使用printf
它来生成转义字符。它理解八进制转义,而不是十六进制。
esc=$(printf '\033')
echo "test" | sed "s,.*,${esc}[31m&${esc}[0m,"
您可以致电tput
在 sed 调用中生成替换文本。该命令查找转义序列术语信息数据库。理论上,使用tput
使您的脚本更加可移植,但实际上您不太可能遇到不使用的终端ANSI 转义码。
echo "test" | sed "s,.*,$(tput setaf 1)&$(tput sgr0),"
答案2
使用起来会更方便tput
tput setaf 1; somecommand; tput sgr0
或者
tput setaf 1
somecommand
tput sgr0
这会将前景设置为红色,运行somecommand
后将以红色显示输出,然后清除颜色序列。这至少适用于bash
,zsh
和ksh
。
请参阅tmux(1)
和terminfo(5)
了解有关您可以使用 执行哪些操作的更多信息tput
。
答案3
还有一种更简单的方法:
要确切知道哪个字节对应于转义字符\033
,您可以执行以下操作:
printf "\033" | xxd -p
你得到
1b
因此转义序列 \033 对应于二进制的字节 0b00011011、十进制的 27 或十六进制的 1b。
好消息:sed 知道十六进制代码!
echo "color test" | sed 's,color,\x1b[31m&\x1b[0m,'
当您知道十六进制时,这是一个更好的解决方案。
答案4
某些终端(例如 iterm 中的 bash)允许您按“ctrl-v”键,然后按“ctrl+[”,它将把文字转义字符放入输入字符串中。如果它有效,您可能会在屏幕上看到字符“^[”,但如果您在其周围移动光标,它会将其视为一个字符,因为它确实在幕后。
要了解发生的情况(并测试这是否可行),您可以键入 ctrl+v,然后键入 ctrl+i。您应该看到制表符已插入到提示字符串中。 CS 的历史解释了为什么会出现这种情况:但事实证明,真正的旧键盘有 ctrl+I 硬键有线发送制表符; Tab 键也发送相同的电信号。
由于这个遗留原因,许多终端的 bash 仍然解释某些 ctrl 代码以映射到那些相同的字符。
Ctrl+I 映射到制表符,而 ctrl+[ 恰好匹配 ascii 转义字符。