和其他高级程序设计语言一样, Shell 提供了用来控制程序和执行流程的命令,包括条件分支和循环结构,用户可以用这些命令创建非常复杂的程序。
( 1 )条件控制:有 if 、 case 等结构。
( 2 )循环控制:有 for 、 while 、 until 等结构。
1 . if 条件语句
控制流 if 的用法如下:
if < 判别命令 > ;
then { 命令清单 1}
else { 命令清单 2} //else 语句可省略
fi
此处, < 判别命令 > 通常是上述的“ test < 表达式>” 命令。如果 < 判别命令 > 返回 0 (对于 test 命令来说,就是其后的 < 表达式 > 成立),则将执行 then 后的命令清单;反之,则执行 else 后的命令清单。这种 if...then...else 的结构还可以多重嵌套,形式如下所示:
if ...
then ...
else if ...
then ...
else if ...
then ...
else
...
fi
fi
fi
eg:#!/bin/bash
if [ "$SHELL" = "/bin/bash" ]; then
echo "your login shell is the bash"
else
echo "your login shell is not bash but $SHELL"
fi
2.case 条件语句
if 条件语句用于在两个选项中选定一项,而 case 条件选择为用户提供了根据字符串或变量的值从多个选项中选择一项的方法,其语法格式如下所示:
case < 变量 > in< 字符串 1> ) {< 命令清单 1>};;
...
< 字符串 n> ) {< 命令清单 n>};;
*) { 其他命令 };;
esac
执行时,将判别 < 变量 > 的值与所列出的 n 个字符串中的哪一个匹配,然后就执行其后的命令清单,直到遇到一对分号( ;; )为止。字符串中可含通配符,如果能同时匹配多个字符串,则只执行第一个匹配字符串后的命令。
在 case 运算式中也可以使用 Shell 的通配符(“ *” ,“?”,“ [ ]” )。通常用“ *” 作为case 命令的最后运算式以便在前面找不到任何相应的匹配项时执行“其他命令行”的命令。
eg:#!/bin/bash
case $1 in
China) echo Beijing;;
USA) echo Washington;;
British) echo London;;
Russia) echo Moskow;;
*) echo Out of my knowledge;;
esac
3.for 语句循环
for 循环的语法结构如下:
for < 循环变量 > [in < 循环变量取值集 >]
do < 命令清单 >
done
如果 for 语句的后半部分被省略,则默认的 < 循环变量取值集 > 就是命令行参数集。如果命令清单中有多条命令,系统会依次执行。
eg:显示 97 年头 3 个月月历的 shell 脚本 abc1 。
#!/bin/bash
for i in 1 2 3
do cal $i 1997
done
4.expr 命令
expr 命令是一个手工命令行计数器,用于在 UNIX/LINUX 下求表达式变量的值,一般用于整数值,也可用于字符串。
格式为:
expr Expression( 命令读入 Expression 参数 , 计算它的值 , 然后将结果写入到标准输出 )
参数应用规则:
用空格隔开每个项;
用 \ ( 反斜杠 ) 放在 shell 特定的字符前面;
对包含空格和其他特殊字符的字符串要用引号括起来;
eg:# expr 14 % 9
5
# expr 1000 + 900
1900
# expr 30 / 3 / 2
5
# expr 30 \* 3 ( 使用乘号时,必须用反斜线屏蔽其特定含义。 )
90
# expr 30 * 3
expr: Syntax error
5.while 循环语句
控制流 while 也是一种循环控制结构,用法是:
while < 判别命令 >
do < 命令清单 >
done
当 < 判别命令 > 返回 0 时(对于 test 命令,就是其后的表达式成立),则执行 do 后的命令清单,然后再重作循环;否则,退出循环。 while 控制经常与前述的 shift 命令结合使用。
eg:加从 0 开始的五个偶数 :
#!/bin/bash
loopcount=0
result=0
while [ $loopcount -lt 5 ]
do
increment=`expr $loopcount \* 2`
result=`expr $result + $increment`
loopcount=`expr $loopcount + 1`
done
echo "result is $result"
6.until 循环语句
until 控制流与 while 控制流用法类似,但作用相反。用法为:
until < 判别命令 >
do < 命令清单 >
done
当 < 判别命令 > 返回非 0 值时,执行 do 后的 < 命令清单 > ,然后循环检查条件;当 < 判别命令 > 返回 0 值时,退出循环。
eg:使用 until 语句创建一个计算 1 ~ 5 的平方的Shell 程序。
#!/bin/bash
int=1
until [ $int –gt 5 ]
do
sq=`expr $int \* $int `
echo $sq
int=`expr $int + 1 `
done
echo “Job completed”
7.break 和 continue 语句
有时需要基于某些准则退出循环或跳过循环步。 shell 提供两个命令实现此功能。
( 1 ) break
( 2 ) continue
break 和 continue 的最大区别在于, break 跳出整个循环,而 contiune 则跳过当次循环的剩余部分并直接进入下一次循环。这两个的用法和 C 语言相同。在这里就不多说了。
8.here 文本
在 shell 脚本中,还可以利用所谓的“ here文本”功能,即可在脚本文件中嵌入一段文档,作为脚本中所使用的命令的标准输入。具体用法为:
< 命令 > <<!
< 作为输入的文本内容 >
!
其中“ !” 符号也可用“ EOF” 、“ END” 等替代。
二,函数
1.在脚本中定义函数
所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至 shell 解释器首次发现它时,才可以使用。下面将自定义一个函数,用于显示当前系统的时间。
Time()
{
echo "The system time now is `date `"
}
2.在脚本中使用函数
函数的调用,只需要使用函数名就可以调用已经定义好的函数。现写一个更完整的脚本 time 来观察函数的调用,内容如下:
#!/bin/bash
#function Time
Time()
{
TM=`date `
echo "The system time now is ${TM}"
}
echo “Now is going to the function Time"
Time
echo “Back from the funtion Time"
3.向函数传递参数
向函数传递参数和向普通脚本传递参数是一样,也是用 $1 , $2 , $3..... ,函数获取到参数以后,会将参数传回给shell 脚本,因此,最好当参数传递进函数后在函数里面定义一个变量来保存它。
eg:#!/bin/bash
# function func_test
func_test()
{
echo “$1”
}
echo “start function”
func_test china
echo “end of function”
输入: bash ./test1
4.从函数中返回
当调用完参数,那么主程序可能需要得到函数的返回值。在函数中得到函数返回值有两种方法:
在函数末尾加 return ,从函数中返回,
用最后的命令状态决定返回值。
返回一个数值,如 0 或 1 。格式如:return 0 或者 return 1 。
eg:#!/bin/bash
func_test()
{
if test –z “$1”
then
echo “none input”
return 0
else
echo “$1”
return 1
fi
}
func_test $1
5.获取函数返回值
用户可以直接在程序调用完函数的时候获取它的返回值。
eg:#!/bin/bash
func_test()
{
if test –z “$1”
then
echo “none input”
return 0
else
echo “$1”
return 1
fi
}
func_test $1
echo $?