
1.11 Linux shell脚本基础
shell是用户和Linux内核之间的接口程序,用户在命令行提示符下输入的每个命令都由shell先解释后传给Linux内核。shell是一款命令语言解释器,拥有内置的shell命令集。此外,shell也能被系统中其他有效的Linux实用程序和应用程序所调用。
shell的主要功能包括以下几个。
命令解释功能:将用户可读的命令转换成计算机可理解的命令,并控制命令执行。
输入/输出重定向:操作系统将键盘作为标准输入、显示器作为标准输出,当这些定向不能满足用户需求时,用户可以在命令中用符号“>”或“<”重新定向。
管道处理:利用管道将一条命令的输出送入另一条命令,实现多条命令组合完成复杂功能。
系统环境设置:用shell命令设置环境变量,维护用户的工作环境。
程序设计语言:shell命令本身可以作为程序设计语言,将多个shell命令组合起来,编写能实现系统或用户所需功能的程序。
市面上有多种shell,例如zshell和fish等,一般使用Bash脚本。
1.11.1 Bash
在屏幕上打印“Hello”:
echo "Hello"
将ABC分配给a:
a=ABC
输出a的值:
echo $a
此时,在屏幕上打印ABC。
将ABC.log分配给b:
b=$a.log
输出b的值:
#echo $b ABC.log
把文件“ABC.log”的内容写入到testfile:
cat $b > testfile
指令“--help”会输出帮助信息。
可以把重复执行的shell脚本写入到一个文本文件。在Linux中,文件后缀名不作为系统识别文件类型的依据,但是可作为用户识别文件的依据,可以简单地将脚本文件以.sh结尾。在Linux下,可以通过vi命令创建一个诸如script.sh的文件,即vi script.sh。创建脚本文件后就可以在文件内用脚本语言要求的格式编写脚本程序了。
在创建的脚本文件中输入以下代码并保存和退出。
#!/bin/bash echo "hello world!"
添加脚本文件的可执行运行权限chmod 777 script.sh后,运行文件./script.sh得到以下结果:
hello world!
注意:shell脚本中用“#”表示注释符,相当于C语言中的注释符“//”。但如果“#”位于第一行开头,并且是“#!”(称为Shebang)形式则例外,它表示该脚本使用后面指定的解释器/bin/sh解释执行。每个脚本程序必须在开头包含这个语句。
使用参数n检查语法错误,例如:
#bash -n ./test.sh
如果shell脚本有语法错误,则会提示错误所在行;否则,不输出任何信息。
if语句的语法格式:

这里的fi就是if反过来写。
为了判断某个命令是否存在,可以使用如下的代码:

判断yum是否存在,可以使用如下的代码:

case语句的语法格式:

这里的esac就是case反过来写。
例如:

这里使用“|”把"jpg"和"jpeg"这两个格式连接到了一起。
下面介绍4种模式匹配。
${variable#pattern}:从$string的前面删除$substring的最短匹配。
${variable%pattern}:从$string的后面删除$substring的最短匹配。
${variable%%pattern}:从$string的后面删除$substring的最长匹配。
使用模式匹配的例子:
x=/home/cam/book/long.file.name echo ${x#/*/} echo ${x%.*} echo ${x%%.*} cam/book/long.file.name long.file.name /home/cam/book/long.file /home/cam/book/long
1.11.2 AWK
典型的AWK程序充当过滤器,从标准输入读取数据,并输出标准的过滤数据。它一次读取数据的一条记录。默认情况下,一次读取一行文本。每次读取记录时,AWK自动将记录分隔到字段中。字段在默认情况下也是由空白分隔的。每个字段被分配给一个变量,该变量有一个数字名称。变量$0表示整个记录,$1表示第一个字段,$2表示第二个字段,依此类推。此外,还设置了一个名为NF的变量,其中包含在记录中检测到的字段数量。下面来试试一个很简单的例子。
过滤ls命令的输出,具体代码如下:
#ls -l ./ | awk '{print $0}'
显示文本文件nohup.out匹配(含有)字符串"sun"的所有行,具体代码如下:
#awk '/sun/{print}' nohup.out
由于显示整个记录(全行)是awk的缺省操作,因此可以省略action项。
再如,要得到Python的版本号,可以使用如下的代码:
#python 2>&1 --version | awk '{print $2}' 2.7.5
这里的“2>&1”的含义是,把标准错误重定向到标准输出。