Shell 脚本编程 —— 秘笈2
<!-- toc -->
<!-- tocstop -->
1.输入和输出
在执行任务时,shell通常会自动打开如下所示的3个标准文档。
文档类型 | 说明 | 文件描述符 |
---|---|---|
stdin | 标准输入文档,通常应对终端的键盘 | 0 |
stdout | 标准输出文档,对应终端的屏幕 | 1 |
stderr | 标准错误输出文档,对应终端的屏幕 | 2 |
下面我们将简单介绍一下标准输入、标准输出、文件描述符、重定向以及格式化输出等。
1.1 基本的输出
使用echo命令显示问本行或变量。
echo "hello,world"
1.2 命令行参数
自变量:是一种shell内置的变量,其值能够自己变动。在函数中随着函数的参数变化,在主程序中随着命令行参数变化。
- $$ Shell本身的PID(ProcessID)
- $! Shell最后运行的后台Process的PID
- $? 最后运行的命令的结束代码(返回值)
- $- 使用Set命令设定的Flag一览
- $* 所有参数列表。如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
- $@ 所有参数列表。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
- $# 添加到Shell的参数个数
- $0 Shell本身的文件名
- $1 即命令行输入的第一个参数
- $2 命令行输入的第二个参数,依此类推 $3....n
除了上述以数字命名的自变量外,还有"@"和"#"。"#"比较简单,就是用于记录参数的个数,不会区分函数和命令行。而"@"就比较麻烦,不用的情况下有些差别,如一般表示参数列表。在主程序中是以空格分隔的所有命令行参数,在函数中是以逗号","分隔的所有函数参数。此外,"$0"永远都是代表脚本的文件名。
1.3 使用read读取文本行
read命令接收标准输入,或其它文件描述符的输入。得到输入后,read命令将数据放入一个标准变量中。利用read读取文件时,每次调用read命令都会读取文件中的"一行"文本。当文件没有可读的行时,read命令将以非零状态退出。
使用read命令读取一行数据方法如下:
1
2
3
4while read myline
do
echo "LINE:"$myline
done < myfile.txt
或者
1
2
3
4cat myfile.txt | while read myline
do
echo "LINE:"$myline
done
此外,使用awk
或for var in file
命令也能完成读取文件中的每行数据的功能。
1.4 文件描述符
当看到在脚本里的这条命令时:
1
sudo kill -9 `ps -elf | grep -v grep | grep $1 | awk '{print $4}'` 1>/dev/null 2>&1
第一感觉告诉我,应该是杀进程的。里面的具体东东,看起来真有点晕,"1>"、"2>"、"/dev/null" 代表什么呢?
0,1,2 是文件描述符,代表标准输入、输出和错误。系统中实际上有12个文件描述符,我们可以任意使用文件描述符3到9。
">",表示命令的结果可以重定向到某个地方。例如:echo hello,world > hello.txt
"/dev/null"代表空设备文件,很多的幽默语句与之有关。"1>/dev/null"表示标准输出重定向到空设备文件,也就是不输出任何信息到终端,说白了就是不显示任何信息。
">&"表示等同于的意思,"2>&1"表示2(错误)的输出重定向等同于1。标准错误输出重定向等同于标准输出,因为之前标准输出已经重定向到了空设备文件,所以标准错误输出也重定向到空设备文件,即也不显示错误信息。
执行命令时,可以指定命令的标准输入、输出和错误,要实现这一点就需要使用文件重定向。">"表示标准输出重定向,">>"表示标准输出重定向做追加操作,"<"表示从标准输入中读入,"<<"表示从标准输入中读入,直至遇到分隔符。
command >> filename 2>&1
把标准输出和错误一起重定向追加到一个文件中。command <filename1>filename2
把command命令以filename1文件作为标准输入,以filename2文件作为标准输出。command <<eof
从标准输入中读入,直至遇到eof分界符。command <&m
从文件描述符m作为标准输入command >&m
把标准输出重定向到文件描述符m中command <&-
关闭标准输入
除了有强大的重定向功能,还可以通过管道把一个命令的输出传递给另一个命令作为输入。管道用竖杠 | 表示。它的一般形式为:命令1 | 命令2
,其中 | 是管道符号。
1.5 格式化输出
提起格式化输出printf,各位一定不会陌生吧。它时echo命令的增强版,与C语言中的printf功能和使用方法都类似。利用format字符串控制输出,%与一个字母的格式指示符用来表示相对应的参数字符串的格式化。
printf命令可用来指定输出字段的宽度以及进行对齐的方式。为实现此目的,接在%后面的格式表达式可采用三个可选用的修饰符以及前置的格式指示符。
%[标志][宽度][.精度]格式说明符,字段的内容默认向右对齐,向左对齐需要指定-标志。如:printf "%5.5G\n"3.1415926
,最后输出结果是3.1415吗?不对!%G要求输入是浮点数,精度是指有效位数的最大位数,别忘了,还得四舍五入,输出结果是3.1416。