shell 之 echo 与 printf 和颜色
printf 和 echo
printf 命令模仿 C 程序库(library)里的 printf() 库程序(library routine)。它几乎复制了该函数的所有功能。
不过在 Shell 层级的版本上,会有些差异。由于 printf 的行为是由 POSIX标准所定义,因此使用 printf 的脚本比使用 echo 移植性好。 如同 echo 命令,printf 命令可以输出简单的字符串:
[root@master ~]#printf "Hello, Shell\n"
Hello, Shell
[root@master ~]#
你应该可以马上发现,最大的不同在于:printf 不像 echo 那样会自动提供一个换行符号。你必须显式 地将换行符号指定成 \n
。
echo -n "Enter your name:" // 参数 - n 的作用是不换行,echo 默认是换行
要使转义符生效,需加参数 -e
echo 输出颜色文本
echo 命令改变样式,以输出不同颜色的文本,必须有 -e 选项 (开启 echo 中的转义)。
在 echo 命令输出之后附加换行,可以使用 n
选项:
$ cat >echo
#!/bin/bash
echo -e "this echo's 2 new lines\n\n"
echo "OK"
echo "The log files have all been done"
echo "$LOGNAME carried them out at `date`"
echo "\"/dev/rmt0"\"
echo "/dev/rmt0"
/dev/rmt0
echo "\"/dev/rmt0\""
"/dev/rmt0"
菜单显示,不必多个 echo 一行行显示,可以一整个 echo
echo "===========================================
| ** unix script test |
| 1 --- num 1 |
| 2 --- num 2 |
| 3 --- num 3 |
| 4 --- num 4 |
==============================================="
事实上,echo 除了 -n options 之外,常用选项还有: -e :启用反斜线控制字符的转换 (参考下表) -E :关闭反斜线控制字符的转换 (预设如此) -n :取消行末之换行符号 (与 -e 选项下的 c 字符同意)
前面讲到,包围在单引号之内的字符都不会有特殊含义,所以单引号本身并不能在一对单引号中出现。但是在前面加上 $ 之后,就可以使用 \ 进行转义了,\ 的转义含义与 C 语言中的相同。
关于 echo 命令所支持的反斜线控制字符如下表:
- \a:ALERT / BELL (从系统喇叭送出铃声)
- \b:BACKSPACE ,也就是向左删除键
- \c:取消行末之换行符号
- \E:ESCAPE,跳脱键
- \f:FORMFEED,换页字符
- \n:NEWLINE,换行字符
- \r:RETURN,回车键
- \t:TAB,表格跳位键
- \v:VERTICAL TAB,垂直表格跳位键
- :ASCII 八进位编码 (以 x 开首为十六进制) :反斜线本身
例一:
$ echo -e "a\tb\tc\nd\te\tf"
a b c
d e f
上例运用 \t 来区隔 abc 还有 def ,及用 \ n 将 def 换至下一行。
例二:
$ echo -e "\141\011\142\011\143\012\144\011\145\011\146"
a b c
d e f
与例一的结果一样,只是使用 ASCII 八进位编码。
例三:
$ echo -e "\x61\x09\x62\x09\x63\x0a\x64\x09\x65\x09\x66"
a b c
d e f
与例二差不多,只是这次换用 ASCII 十六进制编码。
测试变量是否已经设置
有时要测试是否已设置或初始化变量。如果未设置或初始化,就可以使用另一值。此命令格式为:
$ {variable : -value}
意即如果设置了变量值,则使用它,如果未设置,则取新值。例如:
$ COLOUR=blue
$ echo "The sky is ${COLOR:-grey} today"
The sky is grey today
变量 colour 取值 blue,echo 打印变量 colour 时,首先查看其是否已赋值,如果查到,则使用该值。变量 $COLOR 没有设置,所以会打印后面的 grey.
上面的例子并没有将实际值传给变量,需使用下述命令完成此功能:
$ {variable : = value}
下面是一个更实用的例子。查询工资清单应用的运行时间及清单类型。在运行时间及类 型输入时,敲回车键表明用户并没有设置两个变量值,将使用缺省值( 0 3:00 和 Weekly),并 传入 at 命令中以按时启动作业。
#!/bin/bash
# vartest
echo "what time do you wish start the payroll [03:00]:"
read TIME
echo "process to start at ${TIME:=03:00} OK"
echo "Is it a monthly or weekly run [Weekly]:"
read RUN_TYPE
echo "Run type is ${RUN_TYPE:=Weekly}'
at -f $RUN_TYPE $TIME
在输入域敲回车键,输出结果如下:
what time do you wish start the payroll [03:00]:
process to start at 03:00 OK
Is it a monthly or weekly run [Weekly]:
Run type is Weekly
在使用 putty、secureCRT、XShell 等终端仿真器连接 linux 系统时,ls、vim 等工具的输出都含有各种颜色,这些颜色的输出大大地增强了文本的可读性。
通常我们可以使用 echo 命令加 - e 选项输出各种颜色的文本,例如:echo -e "\033[31mRed Text\033[0m"
,可以输出红色的字体 “Red Text”。其中:”\033[31m” 和 “\033[0m” 是 ANSI 转义序列(ANSI escape code/sequence),它控制文本输出的格式、颜色等,大多数的类 unix 终端仿真器都能够解释 ANSI 转义序列。
1. ANSI 颜色序列格式
通用的控制文本颜色的转义序列格式如下:
CSI n1 [;n2 [;…]] m
其中 CSI 全称为 “控制序列引导器”(Control Sequence Introducer/Initiator),也就是上述示例中的 “\033[“(其中 \ 033 是你键盘左上角 Esc 键对应的 ascii 码(八进制))
-
n1、n2 等表示 SGR 参数(下面会列出一些常用的 SGR 参数),用于控制颜色、粗体、斜体、闪烁等文本输出格式;
-
m 表示转义序列结束。
注:\033 是键盘左上角 Esc 键对应的 ASCII 码(8 进制),\033、\x1b 和 \ e 效果一样, 例如:echo -e “\x1b[31mRed Text\e[0m” 也输出红色字体 “Red Text”。
除了 shell 命令可输出颜色,其它语言中也可以使用上述 ANSI 转义序列输出颜色(前提是你使用的终端仿真器能够解析 ANSI 转义序列),以下给出几种主要语言中输出颜色文本的示例。
注:以下程序仅针对类 unix 终端有效,win32 控制台不支持 ANSI 转义序列,因而无效。
常用的 SRG 参数列表如下:
可以选择的编码如下所示 (这些颜色是 ANSI 标准颜色):
编码 | 颜色 / 动作 |
---|---|
0 | 重新设置属性到缺省设置 |
1 | 设置粗体 |
2 | 设置一半亮度 (模拟彩色显示器的颜色) |
4 | 设置下划线 (模拟彩色显示器的颜色) |
5 | 设置闪烁 |
7 | 设置反向图象 |
22 | 设置一般密度 |
24 | 关闭下划线 |
25 | 关闭闪烁 |
27 | 关闭反向图象 |
30 | 设置黑色前景 |
31 | 设置红色前景 |
32 | 设置绿色前景 |
33 | 设置黄色前景 |
34 | 设置蓝色前景 |
35 | 设置紫色前景 |
36 | 设置青色前景 |
37 | 设置白色 (灰色) 前景 |
38 | 在缺省的前景颜色上设置下划线 |
39 | 在缺省的前景颜色上关闭下划线 |
40 | 设置黑色背景 |
41 | 设置红色背景 |
42 | 设置绿色背景 |
43 | 设置黄色背景 |
44 | 设置蓝色背景 |
45 | 设置紫色背景 |
46 | 设置青色背景 |
47 | 设置白色 (灰色) 背景 |
49 | 设置缺省黑色背景 |
\033[2J | 清除屏幕 |
\033[0q | 关闭所有的键盘指示灯 |
\033[1q | 设置 “滚动锁定” 指示灯 (Scroll Lock) |
\033[2q | 设置 “数值锁定” 指示灯 (Num Lock) |
\033[3q | 设置 “大写锁定” 指示灯 (Caps Lock) |
\033[15:40H | 把关闭移动到第 15 行,40 列 |
\007 | 发蜂鸣生 beep |
\a ASCII | 响铃字符(也可以键入 \007) |
\e ASCII | 转义字符(也可以键入 \033) |
\033 与 \e 是一样功能
下面看几个例子:
echo -e "\033[30m 黑色字 \033[0m"
echo -e "\033[31m 红色字 \033[0m"
echo -e "\033[32m 绿色字 \033[0m"
echo -e "\033[33m 黄色字 \033[0m"
echo -e "\033[34m 蓝色字 \033[0m"
echo -e "\033[35m 紫色字 \033[0m"
echo -e "\033[36m 天蓝字 \033[0m"
echo -e "\033[37m 白色字 \033[0m"
echo -e "\033[40;37m 黑底白字 \033[0m"
echo -e "\033[41;37m 红底白字 \033[0m"
echo -e "\033[42;37m 绿底白字 \033[0m"
echo -e "\033[43;37m 黄底白字 \033[0m"
echo -e "\033[44;37m 蓝底白字 \033[0m"
echo -e "\033[45;37m 紫底白字 \033[0m"
echo -e "\033[46;37m 天蓝底白字 \033[0m"
echo -e "\033[47;30m 白底黑字 \033[0m"
控制选项说明 :
m 前面的 0 可以省略。
编码 | 说明 |
---|---|
\033[0m | 关闭所有属性 |
\033[1m | 设置高亮度 |
\033[4m | 下划线 |
\033[5m | 闪烁 |
\033[7m | 反显 |
\033[8m | 消隐 |
\033[30m – 37m | 设置前景色 |
\033[40m – 47m | 设置背景色 |
\033[nA | 光标上移 n 行 |
\033[nB | 光标下移 n 行 |
\033[nC | 光标右移 n 行 |
\033[nD | 光标左移 n 行 |
\033[y;xH | 设置光标位置 |
\033[2J | 清屏 |
\033[K | 清除从光标到行尾的内容 |
\033[s | 保存光标位置 |
\033[u | 恢复光标位置 |
\033[?25l | 隐藏光标 |
\033[?25h | 显示光标 |
顺序无关,只需要记忆数值所代表的含义即可,因为数值已经限定了是背景还是前景之类的
文本终端的显示颜色可以使用 “ANSI 非常规字符序列” 来生成。
例如:echo -e "\033[44;37;5m ME\033[0m COOL"
解释:
“\033[44;37;5m ME”` 设置背景为蓝色,前景为白色,闪烁光标,输出字符 “ME”;
"\033[0m COOL"
重新设置屏幕到缺省设置,输出字符 “COOL”。
“e” 是命令 echo 的一个可选项,它用于激活特殊字符的解析器。”\033” 引导非常规字符序列 (即 “\033[” 表示终端转义字符开始,”\033” 即退出键 < ESC> 的 ASCII 码)。”m” 意味着设置属性然后结束非常规字符序列,这个例子里真正有效的字符是 “44;37;5” 和 “0”。修改 “44;37;5” 可以生成不同颜色的组合,数值和编码的前后顺序没有关系。
echo 显示带颜色,需要使用参数 - e 格式如下: echo -e "\033[字背景颜色; 文字颜色 m 字符串 \ 033[0m"
例如: echo -e "\033[41;37m TonyZhang \033[0m"
echo -e "\e[41;37m TonyZhang \e[0m"
其中 41 的位置代表底色, 37 的位置是代表字的颜色
注:
1、字背景颜色和文字颜色之间是英文的 “”“” 2、文字颜色后面有个 m 3、字符串前后可以没有空格,如果有的话,输出也是同样有空格
一些说明:
前景颜色各数字是对应背景颜色减去 10。 结束非常规字符序列的 “m” 要紧跟前面的数字,不能有空格。 命令也可以写成 echo -e “^[[44;37;5m ME \033[0m COOL”,其中的 “^[” 是先按 Ctrl-V, 然后再按 < ESC> 键产生的。 输出带有颜色的文本,echo 命令必须带有选项 “-e”。 这种方法只能暂时改变 echo 命令输出的文本的样式,logout 后就恢复为默认。修改. bashrc 文件,可以修改默认的显示样式。 如:在. bashrc 文件的最后面追加一行:echo -e ‘\033[47;30m’。
echo 命令的其他用法
光标跳到第 60 列,然后显示一个 OK。 格式:echo -en ‘\033[60G’ && echo OK 说明:”\033[” 是终端转义字符开始,60G 是命令。
添加颜色
添加颜色相当容易,第一步是设计不带颜色的提示行;
添加终端(而不是 bash)可识别的专用转义序列,以使它以彩色显示文本的某些部分。 标准 Linux 终端和 X 终端允许您设置前景(文字)颜色和背景颜色,如果需要,还可以启用 “bold” 字符。
有八种颜色可供我们选择。前景编号 (30-37) 和背景编号 (40-47) 颜色是通过在 PS1 中添加专用序列来选择的──基本上是夹在 “\e[“(转义开方括号)和 “m” 之间数字值。如果指定一个以上的数字代码,则用分号将它们分开。下面是一个颜色代码示例:”\e[0m”
如果将数字代码指定为零,则它就会通知终端将前景、背景和加粗设置重置为它们的默认值。您可能会在提示行结束时使用这个代码,以使您键入的文字成为非彩色的。
我已说明了如何在提示行中添加信息和颜色,但您还可以更进一步。您可以通过在提示行中添加专用代码来使 X 终端(如 rxvt 或 aterm)的标题栏得到动态更新。您所要做的只是将下面的序列添加到您的 PS1 提示行中:
"/e]2;titlebar/a"
只须用您希望其出现在 xterm 标题栏中的文字替换子串 “titlebar” 即可,现在已经一切就绪了!不必使用静态文字;您可以将 bash 转义序列插入标题栏中。请查看下面这个示例,它将用户名、主机名和当前工作目录显示在标题栏中,并定义了一个简短、明亮的绿色提示行:
export PS1="/[/e]2;/u@/H /w/a/e[32;1m/]>/[/e[0m/]"
因为它将全部信息显示在标题栏上,而不是显示在终端上,终端对一行可以显示多少字符有限制。
顺便提一句,确保用 “/[” 和 “/]” 将您的标题栏序列括起来(因为就终端而言,这个序列是非打印序列)。
将大量信息放在标题栏中的问题是,如果您使用非图形终端(如系统控制台),则看不到这些信息。
为了解决这个问题,可以在您的 .bashrc 中添加以下几行:
if ["$TERM" = "linux"]
then
#we're on the system console or maybe telnetting in
export PS1="/[/e[32;1m/]/u@/H > /[/e[0m/]"
else
#we're not on the console, assume an xterm
export PS1="/[/e]2;/u@/H /w/a/e[32;1m/]>/[/e[0m/]"
fi