1、简单命令
简单命令即命令本身,只有一个命令,有些命令有一个或多个参数,它们以空格分隔。
2、多个命令
执行多个命令最简单的方法是使用分号“;”把它们分隔开来,效果是所有的命令会依次执行,即使前面的命令执行失败了,后面的命令也会继续执行,不同于下面介绍的队列命令。退出状态为执行的最后一个命令的退出状态。
3、队列命令
队列命令使用符号”&&“、”||“,在c/c++中,它们也叫短路运算符,前者称为逻辑与,当前面的条件为真是才会判断后面的条件,后者称为逻辑或,当前面的条件为假时才会判断后面的条件;在shell中,前者称为与命令符,后者称为或命令符,使用与命令符分隔的两个命令,当前面的命令成功执行即退出状态为0时才会继续执行后面的命令,使用或命令符分隔的两个命令,当前面的命令执行失败即退出状态非0时才会继续执行后面的命令。使用队列命令的好处就是后面命令的执行与否取决于前面命令的退出状态,而不是像分号分隔的命令会依次全部执行一样,队列命令的退出状态也是执行的最后一个命令的退出状态。
4、管道命令
管道命令使用符号”|“或”|&“分隔两个命令,前者表示把前一个命令的标准输出作为后一个命令的标准输入,前一个命令的错误输出作为后一个命令的标准输出,后者表示把前一个命令的标准输出和错误输出同时作为后一个命令的标准输入。管道中的每个命令都是在自己的子shell中执行的,类似于父子进程的关系,管道的退出状态是最后一个命令的退出状态。
5、后台命令
后台命令在命令的末尾添加符号“&”即可,该命令的执行是异步的在子shell中进行的,命令执行结束前不会阻塞当前shell,当前shell也不会等待命令执行结束而其退出状态为0,操纵系统上的许多服务进程或守护进程就是在后台执行的。后台这个词是相对的,可以理解为一般的命令执行是在前台完成的。在后台命令结束前,可以使用命令“ps”查看其进程号PID,然后使用命令”kill“杀掉这个进程结束命令的执行,也可以进行作用控制,使用命令”bg“查看当前后台命令,使用命令”fg“调度后台命令到前台执行。
提示:对于下面介绍的条件命令和循环命令,在shell脚本中,这些复合命令可以写在一行,也可以分成多行来写,分号相当于换行,如果省略分号,剩余的命令写到下一行。
6、条件命令
if条件——
if条件的几种格式如下:
if test_command; then exec_command; fi
if test_command; then exec_command; else exec_command; fi
if test_command; then exec_command; elif test_command; then exec_command; fi
if test_command; then exec_command; elif test_command; then exec_command; else exec_command; fi
if条件中,if-then配对使用,有且只能有一次,elif-then配对使用,可以有零次或多次,else最多一次,fi表示结束。在多个条件分支中,最多有一个分支的命令exec_command可以执行。测试命令test_command成功执行即退出状态为0时执行对应的exec_command。如果有else分支,其执行的前提是前面的所有条件分支都没有执行。整个if条件命令的退出状态为命令exec_command中执行的最后一个命令的退出状态,如果没有执行任何命令,退出状态为0。
case条件——
case条件命令直接举例说明:
var=1
case $var in
(1) echo "1";;
(2|3) echo "2 3";;
4) echo "4";;
5|6) echo "5 6";;
*) echo "none";;
esac
case条件命令的开始语句为“case one_name in”,结束语句为“esac”,中间是若干模式匹配语句。模式匹配语句左边是一对圆括号,左括号可以省略,括号中是将要匹配的模式,用以匹配“one_name”,匹配模式可以使用“|”匹配多种模式,使用“*”匹配任意模式,如果匹配成功,执行后面的命令,结束符号为两个分号“;;”。两个分号表示,若当前模式匹配成功,只执行当前模式下的命令,不再匹配其它模式。两个分号可以替换为“;&”,表示若当前模式匹配成功后,执行完当前模式下的命令,还会执行下一个模式中的命令,而忽略下一个模式是否匹配成功。两个分号还可以替换为“;;&”,表示若当前模式匹配成功后,执行完当前模式下的命令,还会继续匹配剩余的所有模式,若匹配成功则执行对应的命令。整个case条件命令的退出状态为执行的最后一个命令的退出状态,如果没有执行任何命令,退出状态为0。
7、循环命令
while循环和until循环——
while循环的格式如下:
while test_command; do exec_command; done
until循环的格式如下:
until test_command; do exec_command; done
while循环和until循环的格式相同,但效果相反。当测试命令test_command的退出状态为0(在shell中退出状态为0表示命令执行成功)时,while循环执行后面的命令exec_command,而until循环则直接退出不执行后面的命令exec_command;当测试命令test_command的退出状态非0时,until循环执行后面的命令exec_command,而while循环却直接退出不执行后面的命令exec_command。while循环和until循环的退出状态为命令exec_command中执行的最后一个命令的退出状态,如果没有执行命令exec_command,退出状态为0。对于测试命令test_command来说,还可以直接填写shell关键字true或false。对于while循环来说,true会继续执行后面的命令exec_command, 而false则不会;until循环恰好相反。
for循环——
for循环有两种用法,直接举例说明。
例一:
for ((i=1;i<=10;i+=1)); do echo $i; done
例一的效果是遍历从1到10的整数,并把它们打印出来。
例二:
for var in a bb ccc 1 22 333; do echo $var; done
例二的效果是依次打印关键字in后面的字符串序列。
对于上面提到的几种循环结构,可以像其它语言一样使用关键字break和continue,break表示退出当前循环,continue表示跳过当前循环的当次循环,执行下一次循环。
8、select
select命令是个特殊的命令,用来生成列表项,语法类似于for循环。
select例子如下:
select name in a bb ccc 1 22 333
do
echo $name $REPLY
break
done
执行效果如下:
1) a
2) bb
3) ccc
4) 1
5) 22
6) 333
#?
现在,shell等待我们输入,输入内容保存在系统变量REPLY中,如果其值在列表项的数值范围内,就将变量name赋值为对应的条目,否则将变量name设置为空。如果输入为空,则重新显示列表项;关键字break用于退出select。
提示:圆括号与花括号的区别。有时候,为了把一系列命令当作一个整体来执行,常把他们放入一对圆括号或一对花括号中,但这两种括号是有区别的。首先,圆括号中的命令在子shell中执行,所以像变量赋值这种操作是不会影响当前shell的,而花括号中的命令却是在当前shell中执行的,变量赋值是会影响当前shell的。其次,花括号作为保留字,与命令之间必需有个元字符,如空格,而圆括号作为运算符,不必使用空格。下面列出的命令用法都是合法的。
var=hello
echo $var
(echo $var)
( echo $var)
(echo $var )
( echo $var )
{ echo $var;}
{ echo $var; }