shell脚本编程-检查和测试
在Shell脚本中初学者可能最先想到的测试方法就是查看之前命令返回的值,是0就成功执行,非0就执行失败!
如:
# ls message message # ls message01 ls: cannot access message01: No such file or directory # echo $? 2
A. 使用test命令: test expression
B. 使用 [ 启动一个测试,在写expression,再以 ] 结束测试. (注意:[ 后面有一个空格, ] 前面也有一个空格,否则Shell会报错.)
eg: [ expression ]
文件测试符:(file_operator)
-b FILE | 当文件存在且是个块文件时返回真,否则为假 |
-c FILE | 当文件存在且是个字符设备时返回真,否则为假 |
-d FILE | 当文件村子且是个目录时返回真,否则为假 |
-e FILE | 当文件或者目录存在时返回真,否则为假 |
-f FILE | 当文件存在且为普通文件时返回真,否则为假 |
-x FILE | 当文件存在且为可执行文件时返回真,否则为假 |
-w FILE | 当文件存在且为可写文件时返回真,否则为假 |
-r FILE | 当文件存在且为可读文件时返回真,否则为假 |
-l FILE | 当文件存在且为链接文件时返回真,否则为假 |
-p FILE | 当文件存在且为管道文件时返回真,否则为假 |
-s FILE | 当文件存在且大小不为0时返回真,否则为假 |
-S FILE | 当文件存在且为socket文件时返回真,否则为假 |
-g FILE | 当文件存在且设置了SGID时返回真,否则为假 |
-u FILE | 当文件存在且设置了SUID时返回真,否则为假 |
-k FILE | 当文件存在且设置了sticky时返回真,否则为假 |
-G FILE | 当文件存在且属于有效的用户组时返回真,否则为假 |
-O FILE | 当文件存在且属于有效的用户时返回真,否则为假 |
FILE1 -nt FILE2 | 当FILE1比FILE2新时返回真,否则为假 【-nt:newer than】 |
FILE1 -ot FILE2 | 当FILE1比FILE2旧时返回真,否则为假 【-ot:older than】 |
① test file_operator FILE
# test -e message # echo $? 0 # test -e message01 # echo $? 1
② [ file_operator FILE ] (有空格)
# [ -e message ] # echo $? 0 # [ -e message01 ] # echo $? 1
例如:rwx.sh
#!/bin/bash read -p "What file do you want to test?" filename if [ ! -e "$filename" ];then echo "The file does not exist" exit 1 fi if [ -r "$filename" ];then echo "$filename is readable" fi if [ -w "$filename" ];then echo "$filename is writeable" fi if [ -x "$filename" ];then echo "$filename is executeable" fi
直接上表:字符串测试表
-z "string" | 字符串string为空时返回真,否则为假 |
-n "string" | 字符串string非空时返回真,否则为假 |
"string1" = "string2" | 字符串string1和string2相同时返回真,否则为假 |
"string1" != "string2" | 字符串string1和string2不同时返回真,否则为假 |
"string1" > "string2" | 按照字典排序,字符串string1排在string2之前时返回真,否则为假 |
"string1" < "string2" | 按照字典排序,字符串string1排在string2之后时返回真,否则为假 |
# str1="" --定义空字符串str1 # test -z "$str1" --测试str1是否为空,为空则返回0 # echo $? 0 # test -n "$str1" --测试str1是否非空,非空则返回0,否则返回1 # echo $? 1 # str2="hello" # [ -z "$str2" ] --测试str2是否为空,为空则返回0,否则返回1 # echo $? 1 # [ -n "$str2" ] --测试str2是否非空,非空则返回0,否则返回1 # echo $? 0 # [ "$str1" = "$str2" ]--测试str1和str2是否相同,相同则返回0,否则返回1 # echo $? 1 # [ "$str1" != "$str2" ]--测试str1和str2是否不同,不同则返回0,否则返回1 # echo $? 0 # [ "$str1" \> "$str2" ]--比较str1和str2的大小,需要注意,<和>都需要转义 # echo $? 1 # [ "$str1" \< "$str2" ] # echo $? 0 # [[ "$str1" > "$str2" ]]--如果不想要转义,就使用[[ ]] # echo $? 1 # [[ "$str1" < "$str2" ]] # echo $? 0
整数测试符:
"num1" -eq "num2" | 如果num1等于num2则返回真,否则为假. 【eq:equal】 |
"num1" -gt "num2" | 如果num1大于num2则返回真,否则为假. 【gt:great than】 |
"num1" -lt "num2" | 如果num1小于num2则返回真,否则为假. 【lt:less than】 |
"num1" -ge "num2" | 如果num1大于等于num2则返回真,否则为假. 【ge:great equal】 |
"num1" -le "num2" | 如果num1小于等于num2则返回真,否则为假. 【le:less equal】 |
"num1" -ne "num2" | 如果num1不num2则返回真,否则为假. 【ne:not equal】 |
两种测试方法:
a. test "num1" num_operator "num2"
b. [ "num1" num_operator "num2" ]
例如:
# num1=10 # num2=10 # num3=9 # num4=11 # [ "$num1" -eq "$num2" ] # echo $? 0 # [ "$num1" -gt "$num3" ] # echo $? 0 # [ "$num1" -lt "$num4" ] # echo $? 0 # [ "$num1" -ge "$num2" ] # echo $? 0 # [ "$num1" -le "$num2" ] # echo $? 0 # [ "$num1" -ne "$num3" ] # echo $? 0
逻辑测试符:
!expression | 如果expression为真,则测试结果为假 |
expression1 -a expression2 | expression1 和 expression2同时为真,则测试结果为真 |
expression1 -o expression2 | expression1 和 expression2只要一个为真,则测试结果为真 |
eg:
# [ ! -e /var/log/messages ] # echo $? 1 # [ -e /var/log/messages -a -e /var/log/messages01 ] # echo $? 1 # [ -e /var/log/messages -o -e /var/log/messages01 ] # echo $? 0
逻辑运算符:
! | 逻辑非,对真假取反 |
&& | 逻辑与,链接两个表达式,只有两个表达式为真结果才为真 |
|| | 逻辑或,连接两个表达式,只要有一个表达式为真结果就为真 |
eg:
# ! [ -e /var/log/messages ] # echo $? 1 # [ -e /var/log/messages ] && [ -e /var/log/messages01 ] # echo $? 1 # [ -e /var/log/messages ] || [ -e /var/log/messages01 ] # echo $? 0
其他表达式:
expression1 && expression2 && expression3 -- 一个为假就返回假
[ expression1 -a expression2 -a expression3 ] -- 一个为假就返回假
expression1 || expression2 || expression3 -- 一个为真就返回真
[ expression1 -o expression2 -o expression3 ] -- 一个为真就返回真
如果为如下:
expression && DoWhenExpressionTrue || DoWhenExpressionFalse
解释:首先执行expression,如果返回为真,就继续执行&&后的代码DoWhenExpressionTrue,如果该语句执行成功就执行返回,后否则就执行DoWhenExpressionFalse ,
如果expression执行返回假,就跳过DoWhenExpressionTrue,执行DoWhenExpresionFalse,(简直就是一个隐形的if-then-else语句)
a.if判断结构
如果测试结果为真则运行相关代码.
if expression; then
command
......
fi
# vim score01.sh
#!/bin/bash echo -n "Please input a score:" read SCORE if [ "$SCORE" -lt 60 ];then echo "C" fi if [ "$SCORE" -lt 80 -a "$SCORE" -ge 60 ];tehn echo "B" fi if [ "$SCORE" -ge 80 ];tehn echo "A" fi # chmod 755 score01.sh # ./score01.sh Please input a score:90 A
b.if/else判断结构
该语句完成两个分支的选择:如果if后的判断成立,则执行then后面的内容;否则执行else后面的内容。
if expression;then
command
......
else
command
......
fi
# cat chk_file.sh #!/bin/bash FILE=/var/log/messages #FILE=/var/log/messages01 if [ -e $FILE ];then echo "$FILE exists" else echo "$FILE not exists" fi # chmod 755 chk_file.sh # ./chk_file.sh /var/log/messages exists
c.if/elif/else 判断结构 也就是 if /else if /else 结构
# cat score02.sh #!/bin/bash echo -n "Please inputa score": read SCORE if [ "$SCORE" -lt 60 ]; then echo "C" else if [ "$SCORE" -lt 80 -a "$SCORE" -ge 60 ]; then echo "B" else if [ "$SCORE" -ge 80 ]; then echo "A" fi fi fi # ./score02.sh Please inputa score:90 A
or
# cat score03.sh #!/bin/bash echo -n "Please inputa score": read SCORE if [ "$SCORE" -lt 60 ]; then echo "C" elif [ "$SCORE" -lt 80 -a "$SCORE" -ge 60 ]; then echo "B" else echo "A" fi # ./score03.sh Please inputa score:90 A
与if/elif/else判断结构一样用于分支选择:
case VAR in var1) command1 ;; var2) command2 ;; var3) command3 ;; ... *) command ;; esac
VAR和var1,var2,var3以及*等匹配,其中var1,var2,var3等这些值只能是常量或正则表达式。在无一匹配的情况下匹配最后的默认*,并执行后面的默认命令.
# cat detect_input.sh #!/bin/bash read -p "Giveme a word:" input echo -en "You gave me some " case $input in *[[:lower:]]*) echo -en "Lowercase ";; *[[:upper:]]*) echo -en "Uppercase" ;; *[[:digit:]]*) echo -en "Numerical" ;; *) echo "unkonwn input." ;; esac # chmod 755 detect_input.sh # ./detect_input.sh Giveme a word:woca You gave me some Lowercase # ./detect_input.sh Giveme a word:SDFG You gave me some Uppercase
2015年9月24日18:47:37