shell基础04 结构化命令
几乎和别的编程语言思想一样,只是关键字写法稍有不同。总结主要包括如下几种:if-then,for,while
1. if-then
格式:
if command #根据command的状态码是否为0进行判断,为0才执行then中部分。(判断状态码:echo $? )
then
commands #可以有多条语句
fi
举例:
1 [Hermioner@localhost Documents]$ cat test1.sh 2 #!/bin/bash 3 if pwd 4 then 5 echo "Hello world" 6 fi 7 [Hermioner@localhost Documents]$ ./test1.sh 8 /home/Hermioner/Documents 9 Hello world
缺点:只有if一种选择。
2. if-then-else
格式:
if command
then
commands
else
commands #状态码非0时就可以执行啦
fi
可以嵌套多个if then 语句在else里面。但是这样不利于代码的阅读。为了解决这个问题,可以直接使用elif代替else命令,这样就相当于在原来的else下面再次嵌套了if 语句。并且,紧跟elif后面的else语句也属于elif代码块,它并不属于之前的if then代码块。可以嵌套多个elif。其实elif就相当于JAVA中的else if语句。
缺点:代码逻辑不容易阅读。即使有多种可供的逻辑选择。有时候可以采用case来代替elif,比如判断多个变量是否有匹配:
case variable in
pattern1 | pattern2) commands1;;
pattern3) commands2;;
*) default commands;;
esac
1 [Hermioner@localhost Documents]$ cat test1.sh 2 #!/bin/bash 3 count=1 4 if test 2 -gt 12 5 then 6 echo "2 is greater than 12" 7 elif test $count -eq 1 8 then 9 echo "the value of count is 1" 10 elif test 2 -lt 12 11 then 12 echo "2 is lower than 12" 13 fi 14 [Hermioner@localhost Documents]$ bash test1.sh 15 the value of count is 1
1 [Hermioner@localhost Documents]$ cat test2.sh 2 #!/bin/bash 3 i=a 4 case $i in 5 a | b) 6 echo "a | b";; 7 c) 8 echo "c";; 9 *) 10 echo "default";; 11 esac 12 [Hermioner@localhost Documents]$ bash test2.sh 13 a | b 14 [Hermioner@localhost Documents]$
总结:前面所有的if语句它们的判断条件只能是命令状态码。
3. test命令
为了测试其它条件,我们可以利用工具test来解决。它只支持判断三类条件:1)数值比较;2)字符串比较;3)文件比较
命令格式:
if test condition #condition是test要测试的一系列参数和值,如果条件成立,test命令就会退出并返回退出状态码0------(类似JAVA中的if判断啦)
note: 如果只写test,直接返回非0。如果不想使用test关键字,可以采用如下格式代替,效果一样:
if [ condition ] 方括号必须要和condition之间有空格隔开。
举例:
1 [Hermioner@localhost Documents]$ bash test2.sh 2 hello world 3 [Hermioner@localhost Documents]$ cat test2.sh 4 #!/bin/bash 5 a="hello" 6 if test $a 7 then 8 echo "hello world" 9 else 10 echo "wrong" 11 fi
1 [Hermioner@localhost Documents]$ cat test2.sh 2 #!/bin/bash 3 a="hello" 4 if [ $a ] 5 then 6 echo "hello world" 7 else 8 echo "wrong" 9 fi 10 [Hermioner@localhost Documents]$ bash test2.sh 11 hello world 12 [Hermioner@localhost Documents]$
(1)数值比较 (只能处理整数)
比 较 含义
n1 -eq n2 =
n1 -ge n2 >=
n1 -gt n2 >
n1 -le n2 <=
n1 -lt n2 <
n1 -ne n2 !=
1 [Hermioner@localhost Documents]$ test 1 -eq 2 ;echo $? 2 1 3 [Hermioner@localhost Documents]$ test 1 -ge 2;echo $? 4 1 5 [Hermioner@localhost Documents]$ test 1 -gt 2;echo $? 6 1 7 [Hermioner@localhost Documents]$ test 1 -le 2;echo $? 8 0 9 [Hermioner@localhost Documents]$ test 1 -lt 2;echo $? 10 0 11 [Hermioner@localhost Documents]$ test 1 -ne 2;echo $? 12 0
(2)字符串比较
比较 含义
str1 = str2 检查str1和str2是否相同
str1 !=str2 检查str1和str2是否不同
str1 < str2 检查str1是否小于str2
str1 > str2 检查str1是否大于str2
-n str1 检查str1的长度是否非0
-z str1 检查str1的长度是否为0
note: 操作符两端必须要有空格
1 [Hermioner@localhost Documents]$ str1="a";str2="b" 2 [Hermioner@localhost Documents]$ test $str1 = $str2;echo $? 3 1 4 [Hermioner@localhost Documents]$ test $str1 != $str2;echo $? 5 0 6 [Hermioner@localhost Documents]$ test $str1 \> $str2;echo $? 7 1 8 [Hermioner@localhost Documents]$ test $str1 \< $str2;echo $? 9 0 10 [Hermioner@localhost Documents]$ test -n $str1;echo $? 11 0 12 [Hermioner@localhost Documents]$ test -z $str1;echo $? 13 1
note:关于大于小于符号,必须用转义字符,否则会当成重定向符号。并且,在比较测试中,大写字母被认为是小于小写字母的,和sort刚好相反。因为比较测试使用的是标准的ASCII顺序;而sort命令使用的系统的本地化语言设置中定义的排序顺序。
(3)文件比较
文件测试比较是非常强大的。允许测试Linux文件系统上文件和目录的状态。
比较 描述
-d file 检查file是否存在并是一个目录
-e file 检查file是否存在
-f file 检查file是否存在并是一个文件
-r file 检查file是否存在并可读
-s file 检查file是否存在并非空
-w file 检查file是否存在并可写
-x file 检查file是否存在并可以执行
-O file 检查file是否存在并属当前用户所有
-G file 检查file是否存在并且默认组与当前用户相同
file1 -nt file2 检查file1是否比file2新
file1 -ot file2 检查file1是否比file2旧
1 [Hermioner@localhost Documents]$ ls 2 a test2.sh 3 [Hermioner@localhost Documents]$ test -d a;echo $? 4 0
4. if then可以用的测试条件总结
(1)逻辑测试:采用|| 和&& (或 和 与) 直接if [ condition ] && [ condition ] ,这样来包含多种逻辑组合condition
(2)test中的三种测试 (数值计算和字符串比较的操作符都很简单,不能包含更加复杂的,比如+=这种符号)
(3)使用双括号来计算更加复杂的数值计算;使用双方括号来计算更加复杂的字符串比较
符号 描述
val++ 后增
val-- 后减
++val 先增
--val 先减
! 逻辑求反
~ 位求反
** 幂运算
<< 左位移
>> 右位移
& 位布尔和
| 位布尔或
&& 逻辑和
|| 逻辑或
5. for & while 参考我的 shell练习01
6. until ------和while的判断刚好相反
untile test commands #状态码不为0时才执行do中代码
do
other commands
done
1 [Hermioner@localhost Documents]$ cat test2.sh 2 #!/bin/bash 3 var1=100 4 until [ $var1 -eq 0 ] 5 do 6 echo $var1 7 var1=$[ $var1-25 ] 8 done 9 [Hermioner@localhost Documents]$ bash test2.sh 10 100 11 75 12 50 13 25
7. break
break命令的作用是退出循环。它可以退出任意类型的循环。可以跟数字,也可以不跟。
break n #n代表循环层级,默认为1,代表当前循环。n越大,从内往外。eg:n=2,跳出的是从内往外数的第二个循环。
1 [Hermioner@localhost Documents]$ cat test2.sh 2 #!/bin/bash 3 for (( a=1;a<4;a++ )) 4 do 5 echo "Outer loop:$a" 6 for (( b=1;b<100;b++ )) 7 do 8 if [ $b -gt 4 ] 9 then 10 break 2 11 fi 12 echo " Inner loop:$b" 13 done 14 done 15 [Hermioner@localhost Documents]$ bash test2.sh 16 Outer loop:1 17 Inner loop:1 18 Inner loop:2 19 Inner loop:3 20 Inner loop:4 21 [Hermioner@localhost Documents]$
8. continue
和break一样,仍然可以使用continue n来指定级别。但是,continue是结束本次循环后面的代码,又跳到循环的开始位置准备执行下一次循环。
总结:shell中的结构化语句和JAVA中类似,只是在条件语句的判断上稍有差别,会根据状态码来进行判断;并且,对于括号使用以及括号两边的空格要求极其严格。中括号和小括号使用上也是有差别的。
参考文献:
Linux命令行与shell脚本编程大全(第3版)[美] 布鲁姆(Richard Blum),布雷斯纳汉(Christine Bresnahan) 著,门佳,武海峰 译