一. shell的条件测试
1. 条件测试命令
(1) shell的条件判断是用命令完成的。分别是test命令
,[ 命令
。
(2) 通常将这两个的命令作为if 判断的条件,并执行相应的分流操作。
(3) 在Shell中用if、then、elif、else、fi
这几条命令实现分支控制。
2. 测试示例
利用if嵌套
实现测试一个数据的数值范围,已知这个数小于等于100:
printf "Please Enter random data: " read data
if [ $data -lt 100 ];then
if [ $data -eq 50 ];then
elif [ $data -lt 50 ];then
else
echo "data is gt 50 and lt 100"
fi
else
echo "data is great than 100"
[hb@bogon test-shell]$ ./test.sh
Please Enter random data: 30
data is lt 50
[hb@bogon test-shell]$ ./test.sh
Please Enter random data: 50
data is eq 50
[hb@bogon test-shell]$ ./test.sh
Please Enter random data: 60
data is gt 50 and lt 100
注:如果then在if的下一条语句写,在if判断语句中就不需要加;了
在if判断中除了可以放条件检测命令,还可以放其他的表达式,对这个表达式的要求是:表达式必须要有退出码。这是因为if命令的分流标准就是根据后面的退出码。
利用grep及正则表达式作为表达式作为if 的子命令:
[hb@bogon test-shell]$ cat file
111111111111
aaa222222222
3ccc33333333
ddd444444444
printf "Please Enter file name: "
read filename
if grep -E '[1-9]*' "$filename"
then
echo "yes"
else
echo "no"
fi
[hb@bogon test-shell]$ ./test.sh
Please Enter file name: file
yes
3. 懒逻辑实现判断
我们都知道逻辑运算符与&&,逻辑运算符||可以用来判断条件的真假。
与&&运算符
&&运算符之前的语句如果为真,则继续执行&&后的语句,如果它的条件为真则输出。
[ $data -eq 100 ] && echo "yes"
[ $data -eq 100 ] && {
echo "yes" }
[hb@bogon test-shell]$ ./test.sh
100
yes
yes
或||运算符
||运算符前的语句为假则继续看之后的语句,如果为真则输出。
#[ $data -eq 100 ]||echo "yes"
#[ $data -lt 100 ]||echo "no"
[jinyuyu@localhost progammer]$ ./test2.sh
100
no
注:这两种写法都是利用了&&和||的特性,简化了代码。
4. case分支
和C/C++的switch…case语句的作用相同,都实现了多分支结构。但是shell的case语句比较简单,没有变量的限制,但是它的写法比较奇怪。
示例
利用case语句实现系统操作的多选择,比如某命令的开始(start),停止(stop)等。
#!/bin/bash
case $1 in
[sS]tart | -s )
echo "start ... done"
;;
sto[Pp] | -t )
echo "stop ... done"
;;
[Rr]estart | -rt )
echo "restart ... done"
;;
[sS]tatus | -st )
echo "status ... done"
;;
* )
echo "default"
;;
注:(1)在这个代码中,利用
shell通配符[]
实现了首字母大小写的不区分,利用||实现了选项的作用。更加一般化。
(2)shell脚本的case没有break,直接;;
就可以结束一个匹配项。
(3)通配符*
替代了 C中的defaultx选项。
二. 循环
shell脚本的循环比C/C++简单,但是很类似。
1. 四种循环
(1)利用(())
,(())中的命令可以类C
for ((i=0; i<=10; i++))
do
echo "hello $i"
done
(2)利用for ..in { }
for i in {1,2,3,4}
do
echo "hello $i"
done
for i in {1..10}
do
echo "hello $i"
done
(3)while循环
i=0
while [ $i -le 5 ]
do
echo "hello $i"
let i++
done
(4)util 循环
i=0
until [ $i -ge 10 ]
do
echo "hello $i"
let i++
done
2. 死循环
:
命令可以作为一条空语句的标志,它的退出码始终为真即0.
(1)利用(())
,(())中的命令可以类C
for (( ; ; ))
do
echo "hello bit"
done
(2)利用while语句
while :
do
echo "hello bit"
done
或者
while true
do
echo "hello bit"
done
(3)until循环
until false
do
: #空语句,什么也不做
done
3. 命令行循环
命令行循环就是将写在shell脚本中的语句写到命令行,写法完全一样。
[hb@MiWiFi-R1CL-srv test-shell]$ i=0; while [ $i -le 10 ]; do echo "hello bit $i"; let i++; done
三. 函数
(1)和C语言类似,Shell中也有函数的概念,但是函数定义中没有返回值也没有参数列表。
(2)注意函数体的左花括号{和后面的命令之间必须有空格或换行,如果将后一条命令和右花括号}写在同一行,命令末尾 必须有;号。
(3)在定义myfun()函数时并不执行函数体中的命令,就像定义变量一样,只是给myfun这个名字一个定义, 到后面调用 myfun函数的时候(注意Shell中的函数调用不写括号)才执行函数体中的命令。
示例:
#!/bin/bash
function myfun()
{
echo "I am function!"
}
myfun [hb@MiWiFi-R1CL-srv test-shell]$ ./test.sh
I am function!
函数传参
shell脚本的函数传参可以当作mini脚本,并且在花括号中的变量具有局部特性,出了作用域就销毁。
function myfun()
{
echo $0
echo $1
echo $2
echo $#
echo $@
echo "I am function!"
}
myfun arg1 arg2
[hb@MiWiFi-R1CL-srv test-shell]$ ./test.sh
./test.sh
arg1
arg2
2
arg1 arg2
I am function!
函数返回值
(1)关注退出码
函数调用或者返回时,将shell函数当成命令。只要是命令,那么函数调用成功与否,可以通过 $? 来判定。一般函 数中可以用return命令返回,如果return后面跟一个数字则表示函数的ExitStatus。
function myfun()
{
echo "exec some code"
return 123
}
myfun
echo $?
(2)关注数据
使用 echo 关心他的 数据string。
function myfun()
{
echo "success"
}
ret=$(myfun)
if [ "X$ret" == "Xsuccess" ]; then
echo "exec success"
else
echo "exec fail"
fi
[hb@MiWiFi-R1CL-srv test-shell]$ ./test.sh
exec success