成于坚持,败于止步
if/then结构用来判断命令列表的退出状态码是否为0(因为在UNIX惯例, 0表示"成功"), 如果成功的话, 那么就执行接下来的一个或多个命令,有一个专有命令[ (左中括号, 特殊字符). 这个命令与test命令等价, 并且出于效率上的考虑, 这是一个内建命令. 这个命令把它的参数作为比较表达式或者作为文件测试, 并且根据比较的结果来返回一个退出状态码(0 表示真, 1表示假)
条件判断结构如下:
if [ condition-true]
then
command1
command2
.......
else
command3
command4
.......
if
如果if和then在条件判断的同一行上的话, 必须使用分号来结束if表达式. if和then都是关键字. 关键字(或者命令)如果作为表达式的开头, 并且如果想在同一行上再写一个新的表达式的话, 那么必须使用分号来结束上一句表达式.
if [ -x "$filename" ]; then
不过同样要注意else if的出现,结构如下
if [condition1]
then
command1
......
elif[condition2]
then
command2
.......
else
command3
.....
fi
不过跟我们熟悉的c语言中的判断还是很多不一样,我们看看一个测试条件真假的简单测试程序:
#!/bin/bash
# 小技巧:
# 如果你不能够确定一个特定的条件该如何进行判断,那么就使用if-test结构.
echo "Testing \"0\""
if [ 0 ] # zero
then
echo "0 is true."
else
echo "0 is false."
fi # 0 为真.
echo
echo "Testing \"1\""
if [ 1 ] # one
then
echo "1 is true."
else
echo "1 is false."
fi # 1 为真.
echo
echo "Testing \"-1\""
if [ -1 ] # 负1
then
echo "-1 is true."
else
echo "-1 is false."
fi # -1 为真.
echo
echo "Testing \"NULL\""
if [ ] # NULL (空状态)
then
echo "NULL is true."
else
echo "NULL is false."
fi # NULL 为假.
echo
echo "Testing \"xyz\""
if [ xyz ] # 字符串
then
echo "Random string is true."
else
echo "Random string is false."
fi # 随便的一串字符为真.
echo
echo "Testing \"\$xyz\""
if [ $xyz ] # 判断$xyz是否为null, 但是这只是一个未初始化的变量.
then
echo "Uninitialized variable is true."
else
echo "Uninitialized variable is false."
fi # 未定义的初始化为假.
echo
echo "Testing \"-n \$xyz\""
if [ -n "$xyz" ] # 更加正规的条件检查.
then
echo "Uninitialized variable is true."
else
echo "Uninitialized variable is false."
fi # 未初始化的变量为假.
echo
xyz= # 初始化了, 但是赋null值.
echo "Testing \"-n \$xyz\""
if [ -n "$xyz" ]
then
echo "Null variable is true."
else
echo "Null variable is false."
fi # null变量为假.
echo
xyz=1 # 初始化了, 但是赋null值.
echo "Testing \"-n \$xyz initilized\""
if [ -n "$xyz" ]
then
echo "Initilize variable is true."
else
echo "Null variable is false."
fi
echo
echo "Testing \"false\""
if [ "false" ] # 看起来"false"只不过是一个字符串而已.
then
echo "\"false\" is true." #+ 并且条件判断的结果为真.
else
echo "\"false\" is false."
fi # "false" 为真.
echo
echo "Testing \"\$false\"" # 再来一个, 未初始化的变量.
if [ "$false" ]
then
echo "\"\$false\" is true."
else
echo "\"\$false\" is false."
fi # "$false" 为假.现在, 我们得到了预期的结果.
exit 0
看看结果先:
root@ubuntu:~/resource/study/shell# ./ifelse-test
Testing "0"
0 is true.
Testing "1"
1 is true.
Testing "-1"
-1 is true.
Testing "NULL"
NULL is false.
Testing "xyz"
Random string is true.
Testing "$xyz"
Uninitialized variable is false.
Testing "-n $xyz"
Uninitialized variable is false.
Testing "-n $xyz"
Null variable is false.
Testing "-n $xyz initilized"
Initilize variable is true.
Testing "false"
"false" is true.
Testing "$false"
"$false" is false.
其实这个结果还是让人感觉挺意外的上面的0,1,-1全部为真,随意字符为真,未初始化变量为假,已初始化变量为真,null为假看一个实例验证一下:
#!/bin/bash
one=
if test -z "$one"
then
echo "No command-line arguments."
else
echo "First command-line argument is $one."
fi
one=1
if test -z "$one"
then
echo "No command-line arguments."
else
echo "First command-line argument is $one."
fi
two=
echo
if /usr/bin/test -z "$two" # 与内建的"test"命令结果相同.
then
echo "No command-line arguments."
else
echo "First command-line argument is $two."
fi
two=2
if /usr/bin/test -z "$two" # 与内建的"test"命令结果相同.
then
echo "No command-line arguments."
else
echo "First command-line argument is $two."
fi
echo
three=
if [ -z "$three" ]
then
echo "No command-line arguments."
else
echo "First command-line argument is $three."
fi
three=3
if [ -z "$three" ]
then
echo "No command-line arguments."
else
echo "First command-line argument is $three."
fi
echo
four=
if /usr/bin/[ -z "$four" ]
then
echo "No command-line arguments."
else
echo "First command-line argument is $four."
fi
four=4
if /usr/bin/[ -z "$four" ]
then
echo "No command-line arguments."
else
echo "First command-line argument is $four."
fi
echo
exit 0
看一看执行结果;
root@ubuntu:~/resource/study/shell# ./iftest
No command-line arguments.
First command-line argument is 1.
No command-line arguments.
First command-line argument is 2.
No command-line arguments.
First command-line argument is 3.
No command-line arguments.
First command-line argument is 4.
上面的验证说明他们是完全等价的,毫无疑问
[[ ]]结构和[ ]结构更加通用,在[[ ]]之间的所有字符都不会发生文件名扩展或者单词分割,但是会发生参数扩展和命令替换
#!/bin/bash
echo "For [[ ]] test:"
file=/etc/passwd
if [[ -e $file ]]
then
echo "$file exits"
else
echo "$file not exits"
fi
exit 0
结果:
root@ubuntu:~/resource/study/shell# ./double
For [[ ]] test:
/etc/passwd exits
这里-e是用来测试指定文件是否存在的,在这里使用[ ]其实也是一样的
使用[[ ... ]]条件判断结构, 而不是[ ... ], 能够防止脚本中的许多逻辑错误. 比如, &&, ||, <, 和> 操作符能够正常存在于[[ ]]条件判断结构中, 但是如果出现在[ ]结构中的话, 会报错
在if后面也不一定非得是test命令或者是用于条件判断的中括号结构( [ ] 或 [[ ]] )
看一个例子吧
#!/bin/bash
dir=/dev/pass
if cd "$dir"
then
echo "Now you are in $dir"
else
echo "You can't change to $dir"
fi
dir=/dev/char
if cd "$dir"
then
echo "Now you are in $dir"
else
echo "You can't change to $dir"
fi
dir=/dev/pass
if cd "$dir" 2> /dev/null
then
echo "Now you are in $dir"
else
echo "You can't change to $dir"
fi
exit 0
结果:
root@ubuntu:~/resource/study/shell# ./test1
./test1: line 3: cd: /dev/pass: No such file or directory
You can't change to /dev/pass
Now you are in /dev/char
You can't change to /dev/pass
第一个因为没有指定的目录,所以会自动提示第一行的错误提示,同时if检查到返回状态时false,指定目录存在,没有任何疑问,针对第三个出来为什么没有输出信息,因为2> /dev/null会隐藏错误信息
"if COMMAND"结构将会返回COMMAND的退出状态码.
与此相似, 在中括号中的条件判断也不一定非得要if不可, 也可以使用列表结构,列表结构到底是什么,一块通过实例来理解一下
#!/bin/bash var1=10 var2=20 [ "$var1" -ne "$var2" ] && echo "$var1 is not equal to $var2" dir=/dev/pass [ -d "$dir" ] || echo "$dir directory does not exist" exit 0结果:
root@ubuntu:~/resource/study/shell# ./test2 10 is not equal to 20 /dev/pass directory does not exist这个实例中出现的&& 和 || 就是上面说的列表结构,&&表示前面的返回结果是true则执行后面的echo,|| 表示前面的返回结果是false则指行后面的echo
#!/bin/bash # 算术测试. # (( ... ))结构可以用来计算并测试算术表达式的结果. # 退出状态将会与[ ... ]结构完全相反! (( 0 )) echo "Exit status of \"(( 0 ))\" is $?." # 1 (( 1 )) echo "Exit status of \"(( 1 ))\" is $?." # 0 (( 5 > 4 )) # 真 echo "Exit status of \"(( 5 > 4 ))\" is $?." # 0 (( 5 > 9 )) # 假 echo "Exit status of \"(( 5 > 9 ))\" is $?." # 1 (( 5 - 5 )) # 0 echo "Exit status of \"(( 5 - 5 ))\" is $?." # 1 (( 5 / 4 )) # 除法也可以. echo "Exit status of \"(( 5 / 4 ))\" is $?." # 0 (( 1 / 2 )) # 除法的计算结果 < 1. echo "Exit status of \"(( 1 / 2 ))\" is $?." # 截取之后的结果为 0. (( 1 / 0 )) 2>/dev/null # 除数为0, 非法计算. echo "Exit status of \"(( 1 / 0 ))\" is $?." # 1 exit 0结果:
root@ubuntu:~/resource/study/shell# ./test3 Exit status of "(( 0 ))" is 1. Exit status of "(( 1 ))" is 0. Exit status of "(( 5 > 4 ))" is 0. Exit status of "(( 5 > 9 ))" is 1. Exit status of "(( 5 - 5 ))" is 1. Exit status of "(( 5 / 4 ))" is 0. Exit status of "(( 1 / 2 ))" is 1. Exit status of "(( 1 / 0 ))" is 1.上面实例中$? 获取到上面最后一天指令的返回状态,我们看到了跟我们之前看到的结果是相符的, 如果表达式的结果为0, 那么返回的退出状态码为1, 或者是"假". 而一个非零值的表达式所返回的退出状态码将为0, 或者是"true". 这种情况和先前所讨论的test命令和[ ]结构的行为正好相反,所以第一条返回状态时1,怎if条件就是false
先到这里了,O(∩_∩)O~
我的专栏地址:http://blog.csdn.net/column/details/shell-daily-study.html
待续。。。