Linux shell 学习笔记(8)— 使用结构化命令(if-then 语句、数值比较、字符串比较、文件比较、case 语句)
1. 使用 if-then 語句
最基本的結(jié)構(gòu)化命令就是if-then語句。if-then語句有如下格式。
if command
then
? commands
fi
或者
if command; then
? commands
fi
bash shell 的 if 語句會(huì)運(yùn)行 if 后面的那個(gè)命令。如果該命令的退出狀態(tài)碼是 0(該命令成功運(yùn)行),位于 then 部分的命令就會(huì)被執(zhí)行。如果該命令的退出狀態(tài)碼是其他值, then 部分的命令就不會(huì)被執(zhí)行,bash shell 會(huì)繼續(xù)執(zhí)行腳本中的下一個(gè)命令。fi 語句用來表示 if-then 語句到此結(jié)束。
$ cat test1.sh
#!/bin/bash
# testing the if statement
if pwd
then
echo "It worked"
fi
$
執(zhí)行結(jié)果
$ ./test1.sh
/home/Christine
It worked
$
在 then 部分,你可以使用不止一條命令。可以像在腳本中的其他地方一樣在這里列出多條命令。bash shell 會(huì)將這些命令當(dāng)成一個(gè)塊,如果 if 語句行的命令的退出狀態(tài)值為 0,所有的命令都會(huì)被執(zhí)行;如果 if 語句行的命令的退出狀態(tài)不為 0,所有的命令都會(huì)被跳過。
2. if-then-else 語句
if-then-else 語句在語句中提供了另外一組命令。
if command
then
? commands
else
? commands
fi
當(dāng)if語句中的命令返回退出狀態(tài)碼 0 時(shí),then 部分中的命令會(huì)被執(zhí)行,這跟普通的 if-then 語句一樣。當(dāng) if 語句中的命令返回非零退出狀態(tài)碼時(shí),bash shell 會(huì)執(zhí)行 else 部分中的命令。
3. 嵌套 if 語句
elif 使用另一個(gè) if-then 語句延續(xù) else 部分。
if command1
thencommands
elif command2
thenmore commands
fi
elif 語句行提供了另一個(gè)要測(cè)試的命令,這類似于原始的 if 語句行。如果 elif 后命令的退出狀態(tài)碼是 0,則 bash 會(huì)執(zhí)行第二個(gè) then 語句部分的命令。
$ cat test5.sh
#!/bin/bash
# Testing nested ifs - use elif
#
testuser=NoSuchUser
#
if grep $testuser /etc/passwd
thenecho "The user $testuser exists on this system."
#
elif ls -d /home/$testuser
thenecho "The user $testuser does not exist on this system."echo "However, $testuser has a directory."
#
fi
$
$ ./test5.sh
/home/NoSuchUser
The user NoSuchUser does not exist on this system.
However, NoSuchUser has a directory.
$
可以繼續(xù)將多個(gè) elif 語句串起來,形成一個(gè)大的 if-then-elif 嵌套組合。
if command1
thencommand set 1
elif command2
thencommand set 2
elif command3
thencommand set 3
elif command4
thencommand set 4
fi
每塊命令都會(huì)根據(jù)命令是否會(huì)返回退出狀態(tài)碼 0 來執(zhí)行。記住,bash shell 會(huì)依次執(zhí)行if語句,只有第一個(gè)返回退出狀態(tài)碼 0 的語句中的 then 部分會(huì)被執(zhí)行。
4. test 命令
test 命令提供了在 if-then 語句中測(cè)試不同條件的途徑。如果 test 命令中列出的條件成立,test 命令就會(huì)退出并返回退出狀態(tài)碼 0。如果條件不成立,test 命令就會(huì)退出并返回非零的退出狀態(tài)碼,這使得 if-then 語句不會(huì)再被執(zhí)行。
test 命令的格式非常簡(jiǎn)單。
test condition
condition 是 test 命令要測(cè)試的一系列參數(shù)和值。如果不寫 test 命令的 condition 部分,它會(huì)以非零的退出狀態(tài)碼退出,并執(zhí)行 else 語句塊。
$ cat test6.sh
#!/bin/bash
# Testing the test command
#
if test
thenecho "No expression returns a True"
elseecho "No expression returns a False"
fi
$
$ ./test6.sh
No expression returns a False
$
當(dāng)你加入一個(gè)條件時(shí),test 命令會(huì)測(cè)試該條件。例如,可以使用 test 命令確定變量中是否有內(nèi)容。這只需要一個(gè)簡(jiǎn)單的條件表達(dá)式。
$ cat test6.sh
#!/bin/bash
# Testing the test command
#
my_variable="Full"
#
if test $my_variable
thenecho "The $my_variable expression returns a True"
#
elseecho "The $my_variable expression returns a False"
fi
$
$ ./test6.sh
The Full expression returns a True
$
bash shell 提供了另一種條件測(cè)試方法,無需在 if-then 語句中聲明 test 命令。
if [ condition ]
then
? commands
fi
方括號(hào)定義了測(cè)試條件。注意,第一個(gè)方括號(hào)之后和第二個(gè)方括號(hào)之前必須加上一個(gè)空格,否則就會(huì)報(bào)錯(cuò)。
test 命令可以判斷三類條件:
- 數(shù)值比較
- 字符串比較
- 文件比較
4.1 數(shù)值比較
記住,bash shell只能處理整數(shù)。
| 比較操作 | 描述 |
|---|---|
| n1 -eq n2 | 檢查n1是否與n2相等 |
| n1 -ge n2 | 檢查n1是否大于或等于n2 |
| n1 -gt n2 | 檢查n1是否大于n2 |
| n1 -le n2 | 檢查n1是否小于或等于n2 |
| n1 -lt n2 | 檢查n1是否小于n2 |
| n1 -ne n2 | 檢查n1是否不等于n2 |
$ cat numeric_test.sh
#!/bin/bash
# Using numeric test evaluations
#
value1=10
value2=11
#
if [ $value1 -gt 5 ]
thenecho "The test value $value1 is greater than 5"
fi
#
if [ $value1 -eq $value2 ]
thenecho "The values are equal"
elseecho "The values are different"
fi
#
$
# 運(yùn)行結(jié)果
$ ./numeric_test.sh
The test value 10 is greater than 5
The values are different
$
4.2 字符串比較
| 比較操作 | 描述 |
|---|---|
| str1 = str2 | 檢查str1是否和str2相同 |
| str1 != str2 | 檢查str1是否和str2不同 |
| str1 < str2 | 檢查str1是否比str2小 |
| str1 > str2 | 檢查str1是否比str2大 |
| -n str1 | 檢查str1的長(zhǎng)度是否非0 |
| -z str1 | 檢查str1的長(zhǎng)度是否為0 |
-
檢查字符串相等性
$ cat test7.sh #!/bin/bash # testing string equality testuser=rich # if [ $USER = $testuser ] thenecho "Welcome $testuser" fi $ $ ./test7.sh Welcome rich $ -
字符串大小
$ cat test10.sh #!/bin/bash # testing string length val1=testing val2='' # if [ -n $val1 ] thenecho "The string '$val1' is not empty" elseecho "The string '$val1' is empty" fi # if [ -z $val2 ] thenecho "The string '$val2' is empty" elseecho "The string '$val2' is not empty" fi # if [ -z $val3 ] thenecho "The string '$val3' is empty" elseecho "The string '$val3' is not empty" fi $ $ ./test10.sh The string 'testing' is not empty The string '' is empty The string '' is empty $空的和未初始化的變量會(huì)對(duì)shell腳本測(cè)試造成災(zāi)難性的影響。如果不是很確定一個(gè)變量的內(nèi)容,最好在將其用于數(shù)值或字符串比較之前先通過-n或-z來測(cè)試一下變量是否含有值。
4.3 文件比較
| 比較 | 描述 |
|---|---|
| -d file | 檢查file是否存在并是一個(gè)目錄 |
| -e file | 檢查file是否存在 |
| -f file | 檢查file是否存在并是一個(gè)文件 |
| -r file | 檢查file是否存在并可讀 |
| -s file | 檢查file是否存在并非空 |
| -w file | 檢查file是否存在并可寫 |
| -x file | 檢查file是否存在并可執(zhí)行 |
| -O file | 檢查file是否存在并屬當(dāng)前用戶所有 |
| -G file | 檢查file是否存在并且默認(rèn)組與當(dāng)前用戶相同 |
| file1 -nt file2 | 檢查file1是否比file2新 (但不會(huì)檢查文件是否存在) |
| file1 -ot file2 | 檢查file1是否比file2舊 (但不會(huì)檢查文件是否存在) |
$ cat test11.sh
#!/bin/bash
# Look before you leap
#
jump_directory=/home/arthur
#
if [ -d $jump_directory ]
thenecho "The $jump_directory directory exists"cd $jump_directoryls
elseecho "The $jump_directory directory does not exist"
fi
#
$
$ ./test11.sh
The /home/arthur directory does not exist
$
5. 復(fù)合條件測(cè)試
if-then語句允許你使用布爾邏輯來組合測(cè)試。有兩種布爾運(yùn)算符可用:
-
[ condition1 ] && [ condition2 ]
兩個(gè)條件都必須滿足
-
[ condition1 ] || [ condition2 ]
任意一個(gè)條件滿足
$ cat test22.sh
#!/bin/bash
# testing compound comparisons
#
if [ -d $HOME ] && [ -w $HOME/testing ]
thenecho "The file exists and you can write to it"
elseecho "I cannot write to the file"
fi
$
$ ./test22.sh
I cannot write to the file
$
$ touch $HOME/testing
$
$ ./test22.sh
The file exists and you can write to it
$
6. if-then 高級(jí)特性
bash shell 提供了兩項(xiàng)可在 if-then 語句中使用的高級(jí)特性:
- 用于數(shù)學(xué)表達(dá)式的雙括號(hào)
- 用于高級(jí)字符串處理功能的雙方括號(hào)
6.1 使用雙括號(hào)
雙括號(hào)命令允許你在比較過程中使用高級(jí)數(shù)學(xué)表達(dá)式。test 命令只能在比較中使用簡(jiǎn)單的算術(shù)操作。
雙括號(hào)命令的格式如下:
**(( expression ))**
expression 可以是任意的數(shù)學(xué)賦值或比較表達(dá)式,雙括號(hào)命令符號(hào)如下表所示
| 符號(hào) | 描述 |
|---|---|
| val++ | 后增 |
| val– | 后減 |
| ++val | 先增 |
| –val | 先減 |
| ! | 邏輯求反 |
| ~ | 位求反 |
| ** | 冪運(yùn)算 |
| << | 左位移 |
| >> | 右位移 |
| & | 位布爾和 |
| | | 位布爾或 |
| && | 邏輯和 |
| || | 邏輯或 |
可以在if語句中用雙括號(hào)命令,也可以在腳本中的普通命令里使用來賦值。
$ cat test23.sh
#!/bin/bash
# using double parenthesis
#
val1=10
#
if (( $val1 ** 2 > 90 ))
then(( val2 = $val1 ** 2 ))echo "The square of $val1 is $val2"
fi
$
$ ./test23.sh
The square of 10 is 100
$
**注意,不需要將雙括號(hào)中表達(dá)式里的大于號(hào)轉(zhuǎn)義。**這是雙括號(hào)命令提供的另一個(gè)高級(jí)特性。
6.2 使用雙方括號(hào)
雙方括號(hào)命令提供了針對(duì)字符串比較的高級(jí)特性。雙方括號(hào)命令的格式如下:
**[[ expression ]]**
雙方括號(hào)里的 expression 使用了 test 命令中采用的標(biāo)準(zhǔn)字符串比較。但它提供了 test 命令未提供的另一個(gè)特性——模式匹配(pattern matching)。
$ cat test24.sh
#!/bin/bash
# using pattern matching
#
if [[ $USER == r* ]]
thenecho "Hello $USER"
elseecho "Sorry, I do not know you"
fi
$
$ ./test24.sh
Hello rich
$
7. case 命令
case 命令會(huì)采用列表格式來檢查單個(gè)變量的多個(gè)值:
case variable in
pattern1 | pattern2) commands1;;
pattern3) commands2;;
*) default commands;;
esac
case 命令會(huì)將指定的變量與不同模式進(jìn)行比較。如果變量和模式是匹配的,那么 shell 會(huì)執(zhí)行為該模式指定的命令。可以通過豎線操作符在一行中分隔出多個(gè)模式模式。星號(hào)會(huì)捕獲所有與已知模式不匹配的值。
$ cat test26.sh
#!/bin/bash
# using the case command
#
case $USER in
rich | barbara)echo "Welcome, $USER"echo "Please enjoy your visit";;
testing)echo "Special testing account";;
jessica)echo "Do not forget to log off when you're done";;
*)echo "Sorry, you are not allowed here";;
esac
$
$ ./test26.sh
Welcome, rich
Please enjoy your visit
$
總結(jié)
以上是生活随笔為你收集整理的Linux shell 学习笔记(8)— 使用结构化命令(if-then 语句、数值比较、字符串比较、文件比较、case 语句)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux shell 学习笔记(7)—
- 下一篇: Linux shell 学习笔记(9)—