Shell各种判断结构和运算符的用法是shell编程的基础,了解shell的判断、运算符和一些退出状态对后面的学习有很重要的影响。shell有一个内部命令test经常用于对判断语句进行测试一种或几种状态的条件是否成立。
(1)Linux的shell中的测试命令,用于测试某种条件或某几种条件是否真实存在。测试命令是判断语句和循环语句中条件测试的工具,对判断和运算符的比较测试有很大的帮助。
(2)测试条件为真,返回一个0值;为假,返回一个非0整数值。测试命令有两种方式,一种test expression(表达式);另一种命令格式[ expression ],其中"["是启动测试命令,"]"要与之配对,而且"["和"]"前后的空格必不可少,此方式常作为流程控制语句的判断条件。
(3)整数比较运算符
格式:test "num1" operator "num2"或[ "num1" operator "num2" ],测试结果为真用0表示,为假用非0表示。但只能用于比较数值的大小, 不可用于字符串、文件操作(字符串比较运算符和文件操作符也不能用于其他的操作)。
对浮点型数值进行比较,不能使用整型运算符。
(4)字符串运算符
Shell编程是严格区分大小写的,并注意空格的问题,运算符左右的空格不能少。
字符串赋值和整数赋值没有区别,而shell对变量弱化了,因此不要把字符串比较运算符当作整数比较运算符使用。
(5)文件操作符
文件操作符中的可读、可写、可执行的权限判断经常和chmod命令联用。
(6)逻辑运算符
用于测试多个条件是否为真或为假,也可使用逻辑非测试单个表达式。
表达式:expression1 -a expression1 -aexpression1(并不是所有的运算符都会被执行,只有表达式expression1为真,才会测试expression2为真。只有expression1和expression2都为真才会接着测试expression3是否为真。)
表达式:expression1 -aexpression1 -aexpression1(只要expression1为真,就不用去测试表达式expression2和expression3。只有expression1为假时才会去判断表达式expression2和expression3。同样,只有expression2和expression3同时为假时才会去测试expression3)。
例如:判断文件存在并cd切换目录,[-e /tmp/test -a -d /tmp/test ] || cd /tmp/test或[-e /tmp/test ] && [ -d /tmp/test ] || cd /tmp/test
例如:文件可执行则启动,[-x /etc/init.d/network] && result=`/etc/init.d/network start`
(7)算术运算符
使用let命令来执行算术运算,除法和取余运算过程中要注意除数不能为0,使用算术运算符无法对字符串、文件、浮点型数进行计算(浮点型操作,需要用到专门的函数)。
算术运算符与赋值运算符"="联用,称为算术复合赋值运算符。
(8)位运算符
用于整数间的运算,按位与运算只有两个二进制都为1,结果才为1;按位或运算只要有一个二进制位为1,则结果为1;按位异或运算两个二进制位数相同时,结果为0,否则为1。按位取反运算符将二进制中的0修改成1,1修改成0。
位运算符同样可以同赋值运算符联用,组成复合赋值运算符。
(9)自增自减运算符
自增自减运算符包括前置自增、前置自减、后置自增和后置自减。自增自减操作符的操作元只能是变量,不能是常数或表达式,且该变量值必须为整数型。
#!/bin/sh num1=5 let "a=5+(++num1) " echo "a=$a" num2=5 let "b=5+(num2++) " echo "b=$b"(10)数字常量
Shell脚本或命令默认将数字以十进制的方式进行处理,当使用0作为前缀时表示八进制,当使用0x进行标记时表示十六进制,同时还可使用num#这种形式标记进制数。
#!/bin/sh let "num1=40" echo "num1=$num1" let "num2=040" echo "num2=$num2" let "num3=0x40" echo "num3=$num3"分别使用设置数字常量40的十进制、八进制和十六进制的表示方式,产生的十进制结果是不同的。
#!/bin/sh let "num1=2#1101100110001101" echo "num1=$num1" let "num2=8#50" echo "num2=$num2" let "num3=16#50" echo "num3=$num3"
(1)expr命令
expr一般用于整数值计算和字符串的操作。其操作符名称如下表所示。
注:若expr的操作符是元字符(不是普通字符),需要用转义符将操作符的特殊含义屏蔽,进行数学运算,如expr 2014 \* 2。expr操作符的两端必须有空格,否则不会执行数学运算expr 2014 - 2008。
(2)bc运算器
bc是一种内建的运算器,是bash shell中最常用的浮点数运算工具,包括整型数和浮点数、数组变量、表达式、复杂程序结构和函数。
bc运算器支持的数学运算符号如下表:
bc运算器定义了内建变量scale用于设定除法运算的精度(默认scale=0)。
scale设为4后,除法结果小数点后保留4位。bc -q可以使bc运算器不输出版本信息。
在shell中用bc运算器进行浮点数运算需要使用命令替换的方式。脚本中调用bc运算器一般格式:variable=`echo "options; expression" | bc`。
#!/bin/bash var1=20 var2=3.14159 var3=`echo "scale=5; $var1 ^ 2" | bc` var4=`echo "scale=5; $var3 * $var2" | bc` echo "The area of this circle is:$var4"bc运算器的指数运算计算var1变量的平方,scale=5输出结果的小数点后精确到第5位。
(1)Linux系统,每当命令执行完成后,系统返回一个退出状态。若退出状态值为0,表示命令运行成功;反之若退出状态值不为0,则表示命令运行失败。最后一次执行命令的退出状态值被保存在内置变量"$?"中。
(2)exit命令格式:exit status(status在0~255之间),返回该状态值时伴随脚本的退出,参数被保存在shell变量$?中。
(1)if、then、else语句用于判断给定的条件是否满足,并根据测试条件的真假来选择相应的操作。if/else仅仅用于两分支判断,多分支的选择时需要用到if/else语句嵌套、if/elif/else和case多分支选择判断结构。
(2)if结构
#!/bin/sh echo "Please input a integer:" read integer1 if [ "$integer1" -lt 15 ] then echo "The integer which you input is lower than 15." fi
(3)if/else结构
#!/bin/sh echo "Please input the file which you want to delete:" read file if rm -f "$file" then echo "Delete the file $file sucessfully!" else echo "Delete the file $file failed!" fi(4)if/else语句嵌套
可同时判断三个或三个以上条件,但要注意if与else配对关系,else语句总是与它上面最近的未配对的if配对。
#!/bin/bash #提示用户输入分数(0-100) echo "Please Input a integer(0-100): " read score #判断学生的分数类别 if [ "$score" -lt 0 -o "$score" -gt 100 ] then echo "The score what you input is not integer or the score is not in (0-100)." else if [ "$score" -ge 90 ] then echo "The grade is A!" else if [ "$score" -ge 80 ] then echo "The grade is B!" else if [ "$score" -ge 70 ] then echo "The grade is C!" else if [ "$score" -ge 60 ] then echo "The grade is D!" else echo "The grade is E!" fi fi fi fi fi(4)if/elif/else结构
if/else嵌套在编程中很容易漏掉then或fi产生错误,而且可读性很差,因此引入if/elif/else结构针对某一事件的多种情况进行处理,fi只出现一次,可读性也提高了。
#!/bin/bash echo "Please Input a integer(0-100): " read score if [ "$score" -lt 0 -o "$score" -gt 100 ] then echo "The score what you input is not integer or the score is not in (0-100)." elif [ "$score" -ge 90 ] then echo "The grade is A!" elif [ "$score" -ge 80 ] then echo "The grade is B!" elif [ "$score" -ge 70 ] then echo "The grade is C!" elif [ "$score" -ge 60 ] then echo "The grade is D!" else echo "The grade is E!" fi例:判断输入的年份是否是润年(润年条件:1、能被4整除,但不能被100整除的年份。2、能被100整除,又能被400整除的年份)
#!/bin/sh echo "Please Input a year: " read year let "n1=$year % 4" let "n2=$year % 100" let "n3=$year % 400" if [ "$n1" -ne 0 ] then leap=0 elif [ "$n2" -ne 0 ] then leap=1 elif [ "$n3" -ne 0 ] then leap=0 else leap=1 fi
case结构变量值依次比较,遇到双分号则跳到esac后的语句执行,没有匹配则脚本将执行默认值"*)"后的命令,直到"';;"为止。case的匹配值必须是常量或正则表达式。
#!/bin/bash echo "Please Input a score_type(A-E): " read score_type case "$score_type" in A) echo "The range of score is from 90 to 100 !";; B) echo "The range of score is from 80 to 89 !";; C) echo "The range of score is from 70 to 79 !";; D) echo "The range of score is from 60 to 69 !";; E) echo "The range of score is from 0 to 59 !";; *) echo "What you input is wrong !";; esac
(1)shell的各种运算符是编程的重要环节。IF和CASE条件判断结构的应用,使问题有了多分支的选择。
(2)本文仅简单的介绍重要的基础知识,若要熟练使用,还需要大量的练习。