-----------------------------------------------------------------Sun----------------------------------------------------------
一、条件测试结构
1.if/then 结构
if/then 结构用来判断命令列表的退出状态码是否为 0,因为0表示成功,如果成功的话,这里应该那么就执行接下来的一个或多个命令。
注意: 这里与C语言的等其它语言不同,不能直接使用0或者1作为判断条件,而应该以false
,true
代替。以其它大多数语言相反的true
返回的是0,false
返回的是1
有一个专有命令 [
(左中括号,特殊字符)。这个命令与test
命令等价,由于效率上的考虑,bash将它作为一个内建命令。
#!/bin/bash
# 逐字节比较a b两个文件是否相同
if cmp a b &> /dev/null # 禁止输出.
then echo "Files a and b are identical."
else echo "Files a and b differ."
fi
# 非常有用的"if-grep"结构:
# ------------------------
if grep -q Bash file
then echo "File contains at least one occurrence of Bash."
fi
word=Linux
letter_sequence=inu
if echo "$word" | grep -q "$letter_sequence"
# "-q" 选项是用来禁止输出的.
then
echo "$letter_sequence found in $word"
else
echo "$letter_sequence not found in $word"
fi
# 将打印Command failed
if COMMAND_WHOSE_EXIT_STATUS_IS_0_UNLESS_ERROR_OCCURRED
then echo "Command succeeded."
else echo "Command failed."
fi
2.多级比较
#!/bin/bash
# 这里应该理解为子if/then当做一个整体作为测试条件
if echo "Next *if* is part of the comparison for the first *if*."
if [[ $comparison = "integer" ]]
then (( a < b )) # (( 算数表达式 )), 用作算数运算
else
[[ $a < $b ]]
fi
then
echo '$a is less than $b'
fi
结果: Next *if* id part of the comparison for the first *if*
3.真假判断
#!/bin/bash
# 小技巧:
# 如果你不能够确定一个特定的条件该如何进行判断,
#+ 那么就使用if-test结构.
echo
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
# 什么时候"false"为真?
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" 为假.
echo "Testing \"true\""
if [ "true" ] # 看起来"false"只不过是一个字符串而已.
then
echo "\"true\" is true." #+ 并且条件判断的结果为真.
else
echo "\"true\" is false."
fi # "true”is true
<pre name="code" class="objc">echo "Testing \"$false\""
if [ "$true" ] # 看起来"false"只不过是一个字符串而已.
then
echo "\"$true\" is true." #+ 并且条件判断的结果为真.
else
echo "\"$true\" is false."
fi # "$true" is false.
4.(( )) 结构
(( )) 结构扩展并计算一个算术表达式的值。如果表达式的结果为0,那么返回的退出状态码为1,或者是"假"。
而一个非零值的表达式所返回的退出状态码将为0,或者是"true"。
<span style="font-size:12px;">#!/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
(( 1 / 0 )) 2>/dev/null # 除数为0, 非法计算.
echo "Exit status of \"(( 1 / 0 ))\" is $?." # 1
### 如果删除2>/dev/null 程序会报错。 加上这一段是将1/0标准错误输出到dev/null中。</span>
二、文件测试操作符
1.操作符列举
操作符 | 说明 |
---|---|
-e | 文件存在 |
-f | 表示这个文件是一个一般文件(并不是目录或者设备文件) |
-s | 文件大小不为零 |
-d | 表示这是一个目录 |
-b | 表示这是一个块设备(软盘,光驱,等等) |
-c | 表示这是一个字符设备(键盘,modem,声卡,等等) |
-p | 这个文件是一个管道 |
-h | 这是一个符号链接 |
-L | 这是一个符号链接 |
-S | 表示这是一个socket |
-t | 文件(描述符)被关联到一个终端设备上,这个测试选项一般被用来检测脚本中的 stdin([ -t 0 ]) 或者 stdout([ -t 1 ])是否来自于一个终端 |
-r | 文件是否具有可读权限(指的是正在运行这个测试命令的用户是否具有读权限) |
-w | 文件是否具有可写权限(指的是正在运行这个测试命令的用户是否具有写权限) |
-x | 文件是否具有可执行权限(指的是正在运行这个测试命令的用户是否具有可执行权限) |
-g | set-group-id(sgid)标记被设置到文件或目录上 |
-k | 设置粘贴位 |
-O | 判断你是否是文件的拥有者 |
-G | 文件的group-id是否与你的相同 |
-N | 从文件上一次被读取到现在为止, 文件是否被修改过 |
f1 -nt f2 | 文件f1比文件f2新 |
f1 -ot f2 | 文件f1比文件f2旧 |
f1 -ef f2 | 文件f1和文件f2是相同文件的硬链接 |
! | “非”,反转上边所有测试的结果(如果没给出条件,那么返回真) |
三、二元比较操作符
1.整数比较
<span style="font-size:14px;">if [ "$a"<span style="color:#CC66CC;"> -eq</span> "$b" ] -eq 等于
if [ "$a" <span style="color:#CC66CC;">-ne</span> "$b" ] -ne 不等于
</span><pre><code class="hljs bash"><span class="hljs-keyword">if</span> [ <span class="hljs-string">"<span class="hljs-variable">$a</span>"</span> <span class="hljs-operator">-ge</span> <span class="hljs-string">"<span class="hljs-variable">$b</span>"</span> ] -ge 大于等于
</code>
if [ "$a" -gt "$b" ] -gt 大于
if [ "$a"
-lt "$b" ] -lt 小于
if [ "$a" -le "$b" ] -le 小于等于
(( "$a" < "$b" )) < 在双括号中使用
<pre><code class="hljs bash"></code><pre><code class="hljs bash"><span class="hljs-keyword">(( </span><span class="hljs-string">"<span class="hljs-variable">$a</span>"</span> <span class="hljs-operator"><</span>= <span class="hljs-string">"<span class="hljs-variable">$b</span>"</span> )) <= </code>
<pre><code class="hljs bash"></code><pre><code class="hljs bash"><span class="hljs-keyword">(( </span><span class="hljs-string">"<span class="hljs-variable">$a</span>"</span> <span class="hljs-operator">></span> <span class="hljs-string">"<span class="hljs-variable">$b</span>"</span> )) ></code>
<pre><code class="hljs bash"></code><pre><code class="hljs bash"><span class="hljs-keyword">(( </span><span class="hljs-string">"<span class="hljs-variable">$a</span>"</span> <span class="hljs-operator">>=</span> <span class="hljs-string">"<span class="hljs-variable">$b</span>"</span> )) >=</code>
2.字符串比较
<span style="font-size:14px;">if [ "$a" = "$b" ] = 等于
</span><pre><span style="font-size:14px;"><code class="hljs bash"><span class="hljs-keyword">if</span> [ <span class="hljs-string">"<span class="hljs-variable">$a</span>"</span> == <span class="hljs-string">"<span class="hljs-variable">$b</span>"</span> ] == 等于
</code></span>
if [ "$a" != "$b" ] != 不等于
if [ [ "$a" < "$b" ] ] < 小于
if [ "$a" \< "$b" ] <在[] 中需要转义
if [ [ "$a" > "$b" ] ] > 大于
if [ "$a" \> "$b" ]
>在[] 中需要转义
3.算术比较与字符串比较
#!/bin/bash
a=4
b=5
#整型
if [ "$a" -ne "$b" ] 4 != 5
then
echo "$a is not equal $b"
echo "(arithmatic comparison)"
fi
#字符型
if [ "$a" != "$b" ] ASCII 52 != ASCII 53
then
echo "$a is not equal $b"
echo "(string comparison)"
fi
4.检查字符串是否为null
[ ] 测试操作符能够独立检查string是否为null.
# 如果字符串并没有被初始化, 那么它里面的值未定义.
# 这种状态被称为"null" (注意这与零值不同).
if<span style="color:#CC66CC;"> [<strong> -n $string1 ] </strong></span> # $string1 没有被声明和初始化.
then
echo "String \"string1\" is not null."
else
echo "String \"string1\" is null."
fi
# 错误的结果.
# 显示$string1为非null, 但显然这个变量并没有被初始化.
if [ -n <strong><span style="color:#CC66CC;">"$string1"</span></strong> ] # 这次$string1被引号扩起来了.
then
echo "String \"string1\" is not null."
else
echo "String \"string1\" is null."
fi
if [ $string1 ] #
then
echo "String \"string1\" is not null."
else
echo "String \"string1\" is null."
fi
后两种情况都能检测处 string 为空。
if [ $string1 ] 只有一个参数, "]"
if [ "$string1" ] 有两个参数, 一个是空的"$string1", 另一个是"]"
string="a = b"
if [ $string ]
then
echo "string \"string\" is not null"
else
echo "string \"string\" is null"
fi
明明给 string 赋值了,结果却仍为空。就是因为 if中只有一个 “]” 参数。
5.compound 和 comparison
-a
逻辑与exp1 -a exp2 如果表达式 exp1 和 exp2 都为真的话,那么结果为真。
-o
逻辑或exp1 -o exp2 如果表达式 exp1 和 exp2 中至少有一个为真的话,那么结果为真。
注意:
这与Bash中的比较操作符 && 和 || 非常相像,但是这个两个操作符是用在双中括号结构中的。
[[ condition1 && condition2 ]]
-o
和-a
操作符一般都是和test命令或者是单中括号结构一起使用的
if [ "$exp1" -a "$exp2" ]