接下来以bash为例向大家介绍shell程序设计的高级部分,即shell编程的流程控制、调试方法及shell程序的运行方法,顺便也向大家介绍一下bash的内部命令。
和其他高级程序设计语言一样,shell提供了用来控制程序执行流程的命令,包括条件分支和循环结构,用户可以用这些命令建立非常复杂的程序。
与传统的语言不同的是,shell用于指定条件值的不是布尔表达式,而是命令和字符串。
10.4.1 test测试命令
test命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试,其测试符和相应的功能分别如下。
1.数值测试
-eq:等于则为真。
-ne:不等于则为真。
-gt:大于则为真。
-ge:大于等于则为真。
-lt:小于则为真。
-le:小于等于则为真。
2.字符串测试
=:等于则为真。
!=:不相等则为真。
-z字符串:字符串长度伪则为真。
-n字符串:字符串长度不伪则为真。
3.文件测试
-e文件名:如果文件存在则为真。
-r文件名:如果文件存在且可读则为真。
-w文件名:如果文件存在且可写则为真。
-x文件名:如果文件存在且可执行则为真。
-s文件名:如果文件存在且至少有一个字符则为真。
-d文件名:如果文件存在且为目录则为真。
-f文件名:如果文件存在且为普通文件则为真。
-c文件名:如果文件存在且为字符型特殊文件则为真。
-b文件名:如果文件存在且为块特殊文件则为真。
另外,Linux还提供了与(!)、或(-o)、非(-a)三个逻辑操作符用于将测试条件连接起来,其优先级为“!”最高,“-a”次之,“-o”最低。
同时,bash也能完成简单的算术运算,格式如下:
[
e
x
p
r
e
s
s
i
o
n
]
例
如
:
v
a
r
1
=
2
v
a
r
2
=
[expression] 例如: var1=2 var2=
[expression]例如:var1=2var2=[var110+1]
则var2的值为21。
10.4.2 if条件语句
shell程序中的条件分支是通过if条件语句来实现的,其一般格式为
if条件命令串
then
条件为真时的命令串
else
条件为假时的命令串
fi
例如:
#!/bin/bash
if [ “$1” = “” ] || [ “$2” = “” ]
then
echo “Please enter file name”
exit 1
fi
if [ -e $2 ]
then
echo “The file already exists”
until [ ! -f $2 ]
do
sleep 1
done
fi
if [ ! mv $1 $2
]
then
echo “mv sucessful”
else
echo “mv error”
fi
10.4.3 for循环
for循环对一个变量的可能值都执行一个命令序列。赋给变量的几个数值既可以在程序内以数值列表的形式提供,也可以在程序以外以位置参数的形式提供。for循环的一般格式为
for变量名
[in数值列表]
do
若干个命令行
done
变量名可以是用户选择的任何字符串,如果变量名是var,则在in之后给出的数值将顺序替换循环命令列表中的$var。如果省略了in,则变量var的取值将是位置参数。对变量的每一个可能的赋值都将执行do和done之间的命令列表。例如:
#!/bin/bash
counter=0
for files in *
do
counter=expr $counter + 1
done
echo "There are KaTeX parse error: Expected 'EOF', got '#' at position 397: …是总为0或总为非0。 例1: #̲!/bin/bash echo…n
echo “$n”
while [
n
−
g
t
0
]
d
o
s
d
=
n -gt 0 ] do sd=
n−gt0]dosd=((
n
n
=
n % 10 )) # get Remainder n=
nn=(( KaTeX parse error: Expected 'EOF', got '#' at position 12: n / 10 )) #̲ get next digit…( echo
r
e
v
rev
revsd)
done
echo “$on in a reverse order $rev”
例2:
until [ ! -f $2 ]
do
sleep 1
done
fi
if [ ! mv $1 $2
]
then
echo “mv sucessful”
else
echo “mv error”
fi
10.4.5 case条件选择
if条件语句用于在两个选项中选定一项,而case条件选择为用户提供了根据字符串或变量的值从多个选项中选择一项的方法,其格式为
case string in
exp-1)
若干个命令行1
;;
exp-2)
若干个命令行2
;;
……
)
其他命令行
esac
shell通过计算字符串string的值,将其结果依次和表达式exp-1、exp-2等进行比较,直到找到一个匹配的表达式为止,如果找到了匹配项则执行它下面的命令,直到遇到一对分号(;;)为止。
在case表达式中也可以使用shell的通配符(“”、“?”、“[ ]”),通常用“”作为case命令的最后表达式,以便使在前面找不到任何相应的匹配项时执行“其他命令行”的命令。例如:
#!/bin/bash
echo “Hit a key, then hit return.”
read Keypress
case “$Keypress” in
[A-Z] ) echo “Uppercase letter”;;
[a-z] ) echo “Lowercase letter”;;
[0-9] ) echo “Digit”;;
- ) echo “Punctuation, whitespace, or other”;;
esac
10.4.6 无条件控制语句break和continue
break用于立即终止当前循环的执行,而contiune用于不执行循环中后面的语句而立即开始下一个循环的执行。这两个语句只有放在do和done之间时才有效。
10.4.7 函数定义
在shell中还可以定义函数。函数实际上也是由若干条shell命令组成的,因此它与shell程序形式上是相似的,不同的是它不是一个单独的进程,而是shell程序的一部分。函数定义的基本格式为
functionname
{
若干命令行
}
调用函数的格式为
functionname param1 param2……
shell函数可以完成某些例行的工作,而且还可以有自己的退出状态,因此函数也可以作为if、while等控制结构的条件。
在函数定义时不用带参数说明,但在调用函数时可以带有参数,此时shell将把这些参数分别赋予相应的位置参数$1、 2 、 … 、 2、…、 2、…、*。