Shell输出方式
在执行任务时,shell通常会自动打开如下所示的3个标准文档。
Stdout:标准输出文档,对应终端的屏幕,文件描述符为1。
Stdout:标准错误输出文档,对应终端的屏幕,文件描述符为2。
Stdin:标准输入文档,通常对应终端的键盘,文件描述符为0。
接下来简单说说标准输入、标准输出、文件描述符、重定向等知识点。
1)echo输出
在Shell中我们一般使用echo命令输出文本行或变量,如,输出变量:
1 2 |
$ echo $LANG en_US.UTF-8 |
或
1 2 |
$ echo "Character: $LANG" en_US.UTF-8 |
输出文本:
1 |
$ echo [options] "Hello world" |
-e:表示启用解释反斜杠转义,默认是-E表示禁止转义;
-n:表示禁用最后的换行,echo本身默认最后会输出一个换行;
支持的反斜杠转义如下:
1 2 3 4 5 6 7 |
\a #发出警告声;如echo -e "\aName"; \b #删除前一个字符;如echo -e "\bName"; \c #最后不加上换行符号;如echo -e "Name\c"; \f #换行但光标仍旧停留在原来的位置;如echo -e "Name\fName"; \n #换行且光标移至行首;如 echo -e "Name\nName"; \r #光标移至行首,但不换行;echo -e "Name\rName"; \t #插入tab;如echo -e "Name\tName"; |
2)Printf输出
还提供一种格式化输出方式printf,它是echo命令的增强版,但凡熟悉C语言或Awk的,都应该熟悉printf的功能和使用方法。使用printf必须说明的两点是:
1、printf的默认输出没有换行,换行需要自己加“\n”。
2、printf支持格式化输出,要不怎么能叫printf呢。
printf命令模仿C程序库(library)里的printf()库程序(library routine)。它几乎复制了该函数的所有功能。不过在Shell层级的版本上,会有些差异。由于printf的行为是由POSIX标准所定义,因此使用printf的脚本比使用echo移植性好。如同echo命令,printf命令可以输出简单的字符串:
1 |
$ printf "Hello, Shell\n" |
你应该可以马上发现上面说的第一点了,printf不像echo那样会自动提供一个换行符号,你必须显式地将换行符号指定成\n。
printf命令的完整语法有两个部分:
1 |
$ printf format-string [arguments...] |
第一部分为描述格式规格的字符串,用来描述输出的排列方式,最好为此字符串加上引号。此字符串包含按字面显示的字符以及格式声明,格式声明时特殊的占位符,用来描述如何显示相应的参数。
第二部分是与格式声明相对应的参数列表,例如一系列的字符串或变量值。格式声明由两部分组成:百分比符号(%)和指示符。最常用的格式指示符有两个,%s用于字符串,而%d用于十进制整数。
printf格式指示符表如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
%b #相对应的参数被视为含有要被处理的转义序列之字符串; %c #ASCII字符,显示相对应参数的第一个字符; %d, %i #十进制整数; %e #浮点格式; %E #浮点格式; %f #浮点格式; %g #%e或%f转换,看哪一个较短,则删除结尾的零; %G #%E或%f转换,看哪一个较短,则删除结尾的零; %o #不带正负号的八进制值; %s #字符串; %u #不带正负号的十进制值; %x #不带正负号的十六进制值,使用a至f表示10至15; %X #不带正负号的十六进制值,使用A至F表示10至15; %% #字面意义的%; |
根据POSIX标准:浮点格式%e、%E、%f、%g与%G是“不需要被支持”。这是因为awk支持浮点预算,且有它自己的printf语句。这样Shell程序中需要将浮点数值进行格式化的打印时,可使用小型的awk程序实现。然而,内建于bash、ksh93和zsh中的printf命令都支持浮点格式。
格式字符串中,一般字符会按字面显示。转义序列则像echo那样,解释后再输出成相应的字符。格式声明以%符号开头,并以定义的字母集中的一个来结束,用来控制相应参数的输出。例如%s用于字符串的输出:
printf命令可用来指定输出字段的宽度以及进行对齐的方式。为实现此目的,接在%后面的格式表达式可采用三个可选用的修饰符(modifier)以及前置的格式指示符(format specifier),如下:
%[标志][宽度][.精度]格式指示符
标志可选,默认对输出进行左对齐,如果加”-“表示以由对齐为准。
宽度可选,字段以宽度为数字值,指定字段宽度时,字段的内容默认为向右对齐,如果你希望文字向左靠,必须指定-标志。这样:“%-10s”会在一个有10个字符宽度的字段里,输出一个向左对齐的字符串。如果字符串少于10个字符,则字段将以空白填满。如下示例:
1 2 |
$ printf "%-10s\n" hello hello |
如果不加”-“,默认是由对齐,如下:
1 2 |
$ printf "%10s\n" hello hello |
其中字符串”hello”可以为变量命令,可以有多个,如下示例:
1 2 3 4 |
$ aa=hello $ bb=world $ printf "%10s%15s\n" $aa $bb hello world |
上面这种方式是填充,如果变量值不满足我们给定的字符个数就使用空格填充。
格式化字符串的时候注意,如果有中文和英文混合输出的,可能格式跟你预想的不一样,因为中文和英文所占的字符长度是不一样的(这跟字符集有关),如下:
1 2 3 4 |
$ expr length '中文' 6 $ expr length '12' 2 |
1 2 3 4 |
$ printf "%10s\n" 中文 中文 $ printf "%10s\n" 12 12 |
下面这种方式是占位,不管变量值为多少我们给定的宽度始终不变。
1 2 |
$ printf "%10s$aa%5s$bb\n" hello world |
根据使用场景不同,使用方式也不同。
字段的内容默认向右对齐,向左对齐需要指定-标志。例如:
1 |
$ printf "%5.5G\n" 3.1415926 |
最后输出结果是3.1415吗?不对,%G要求输入是浮点数,精度是指有效位数的最大位数,别忘了,还得四舍五入,输出结果是3.1416。
精度的意义
1 2 3 4 5 6 7 8 9 |
%d,%i,%o,%u,%x,%X #要打印的最小位数,当值的位数小于此数字时,会在前面补零,默认精度(precision)为1; %e,%E #要打印的最小位数,当值的位数小于此数字时,会在小数点后面补零,默认精度为6.精度为0时则表示不显示小数点; %f #小数点右边的位数; %g,%G #有效位数(significant digit)的最大数目; %s #要打印字符的最大数目; |
如,把数值补全。
1 2 3 4 |
$ for i in `seq 1 3`;do printf "%02d\n" $i; done; 01 02 03 |
Shell输入方式
在Shell中read命令接收标准输入,或其他文件描述符的输入。得到输入后,read命令将数据放入一个标准变量中。利用read读取文件时,每次调用read命令都会读取文件中的“一行”文本。当文件没有可读行时,read命令将以非零状态退出。在Shell中read一般都用于脚本中用来接收用户的输入。
read使用方式:
1 2 3 |
$ read [OPTIONS] VAR_NAME -p "" #给提示信息; -t # #设置超时时间单位秒; |
如使用-p
1 2 3 4 |
$ read -p "Input your name:" NAME Input your name:eric $ echo $NAME eric |
使用read命令读取文本一行数据方法可以参考一下这个while循环代码:
1 2 3 4 5 6 7 8 |
$ echo "1" >> /tmp/myfile.txt $ echo "2" >> /tmp/myfile.txt $ cat test.sh #!/bin/bash # while read myline; do echo "LINE:"$myline done < /tmp/myfile.txt |
或
1 2 3 4 5 |
#!/bin/bash # cat myfile.txt | while read /tmp/myline; do echo "LINE:"$myline done |
PS:使用awk或for VAR_NAME in file命令也能完成读取文件中的每行数据的功能。
使用read命令读取文本单个字段数据的方法可以参考一下这个while循环代码:
1 2 3 4 5 6 7 8 |
$ cat /tmp/list.txt Larry Linus $ cat test.sh #!/bin/bash # while read A B; do echo "$A and $B" done < /tmp/list.txt |
文件描述符
如果你在脚本中看到这条命令时:
1 |
$ kill -9 `ps -elf | grep -v grep | grep $1 | awk '{print $4}'` 1>/dev/null 2>&1 |
这条命令是杀死进程的,里面的ps、grep、awk相信都熟悉,而“1>”、“2>”、“/dev/null”代表什么呢?在shell介绍章节中说过重定向但是没有细说。其中:
0、1、2是文件描述符,代表标准输入、输出和错误。系统中实际上有12个文件描述符,我们可以任意使用文件描述符3到9。
“/dev/null”代表空设备文件,“1> /dev/null”表示标准输出重定向到空设备文件,也就是不输出任何信息到终端,说白了就是不显示任何信息。
“>&”表示等同于的意思,“2>&1”表示2的输出重定向等同于1,标准错误输出重定向等同于标准输出,因为之前标准输出已经重定向到了空设备文件,所以标准错误输入也重定向到空设备文件。
Shell字体颜色控制
先给个实例看看,然后根据这个实例介绍一下关于颜色控制方法。
1 2 |
$ echo -e "\033[1;31mHello\033[0m" Hello |
-e:开启反斜杠转义
\033[ :表示开始控制符
1 :表示字体加粗,除了加粗之外还有以下几种输出格式
1 –表示加粗
4 –表示带下划线
5 –表示闪烁
7 –表示把前景和背景反过来
; :分号用于区分输出格式控制和输出颜色控制
31 :其中3表示开启字体颜色显示,而1表示字体颜色选择
1 –表示颜色为red
2 –表示green
3 –表示yellow
4 –表示blue
5 –表示pink
6 –表示azure
0 –表示Gray
Hello :表示为真正的显示主体内容
\033[0m :表示结束控制符