Shell
3.1 運算符
3.1.1 算數運算符
在Shell腳本中,算術運算符用于執行基本的數學運算。Shell支持多種算術運算符,包括加、減、乘、除等。以下是關于Shell算術運算符的一些方法以及相應的示例說明:
加法:
a=10
b=20
c=$((a + b))
echo $c # 輸出:30
$((a + b))
表示把a
和b
的值相加,并將結果賦給變量c
。
減法:
a=30
b=20
c=$((a - b))
echo $c # 輸出:10
$((a - b))
表示把a
和b
的值相減,并將結果賦給變量c
。
乘法:
a=10
b=20
c=$((a * b))
echo $c # 輸出:200
$((a * b))
表示把a
和b
的值相乘,并將結果賦給變量c
。
除法:
a=30
b=3
c=$((a / b))
echo $c # 輸出:10
$((a / b))
表示把a
和b
的值相除,并將結果賦給變量c
。需要注意的是,如果除數為0,會導致腳本執行錯誤。
取余:
a=30
b=4
c=$((a % b))
echo $c # 輸出:2
$((a % b))
表示把a
除以b
的余數,并將結果賦給變量c
。
自增:
a=10
((a++))
echo $a # 輸出:11
((a++))
表示將變量a
的值自增1,即等價于a = a + 1
。
自減:
a=10
((a--))
echo $a # 輸出:9
((a--))
表示將變量a
的值自減1,即等價于a = a - 1
。
通過這些算術運算符,可以在Shell腳本中執行基本的數學運算,對變量進行自增和自減操作。需要注意的是,算術運算符需要使用$((...))
或((...))
語法進行運算,而不能直接使用數學表達式。
3.1.2 關系運算符
在Shell腳本中,關系運算符用于比較兩個值之間的關系,返回布爾值(真或假)。Shell提供了多種關系運算符,包括 -eq
、-ne
、-gt
、-lt
、-ge
和 -le
,分別用于判斷相等、不相等、大于、小于、大于等于和小于等于等關系。以下是關于Shell關系運算符的詳細介紹以及相應的示例說明:
-eq:相等
-eq
用于判斷兩個值是否相等,如果相等則返回true。
示例:
a=10
b=10
if [ $a -eq $b ]; thenecho "a 等于 b"
fi
輸出:
a 等于 b
-ne:不相等
-ne
用于判斷兩個值是否不相等,如果不相等則返回true。
示例:
a=10
b=20
if [ $a -ne $b ]; thenecho "a 不等于 b"
fi
輸出:
a 不等于 b
-gt:大于
-gt
用于判斷左邊的值是否大于右邊的值,如果是則返回true。
示例:
a=30
b=20
if [ $a -gt $b ]; thenecho "a 大于 b"
fi
輸出:
a 大于 b
-lt:小于
-lt
用于判斷左邊的值是否小于右邊的值,如果是則返回true。
示例:
a=30
b=40
if [ $a -lt $b ]; thenecho "a 小于 b"
fi
輸出:
a 小于 b
-ge:大于等于
-ge
用于判斷左邊的值是否大于等于右邊的值,如果是則返回true。
示例:
a=30
b=30
if [ $a -ge $b ]; thenecho "a 大于等于 b"
fi
輸出:
a 大于等于 b
-le:小于等于
-le
用于判斷左邊的值是否小于等于右邊的值,如果是則返回true。
示例:
a=30
b=30
if [ $a -le $b ]; thenecho "a 小于等于 b"
fi
輸出:
a 小于等于 b
通過使用這些關系運算符,可以在Shell腳本中進行條件判斷,根據不同的關系運算結果執行相應的操作。需要注意的是,關系運算符需要在方括號中使用,并且變量周圍需要有空格,以確保運算符正確解析。
3.1.3 邏輯運算符
在Shell腳本中,邏輯運算符用于對多個條件進行邏輯操作,返回布爾值(真或假)。Shell提供了多種邏輯運算符,包括邏輯或(-o
或 ||
)、邏輯與(-a
或 &&
)、邏輯非(!
)等。以下是關于Shell邏輯運算符的詳細介紹以及相應的示例說明:
邏輯或(-o 或 ||)
-o
或 ||
表示邏輯或運算符,左右兩邊的條件只要有一個滿足就返回 true。
示例:
a=10
b=20
if [ $a -eq 10 -o $b -eq 30 ]; thenecho "a 等于 10 或者 b 等于 30"
fi
輸出:
a 等于 10 或者 b 等于 30
邏輯與(-a 或 &&)
-a
或 &&
表示邏輯與運算符,左右兩邊的條件都滿足才返回 true。
示例:
a=10
b=20
if [ $a -eq 10 -a $b -eq 20 ]; thenecho "a 等于 10 并且 b 等于 20"
fi
輸出:
a 等于 10 并且 b 等于 20
邏輯非(!)
!
表示邏輯非運算符,對條件取反,如果條件為假,則返回 true。
示例:
a=10
if ! [ $a -eq 20 ]; thenecho "a 不等于 20"
fi
輸出:
a 不等于 20
可以組合使用邏輯運算符,實現復雜的條件判斷。例如,使用邏輯或和邏輯與運算符進行混合操作:
示例:
a=10
b=20
c=30
if [ $a -eq 10 -a $b -ne 30 ] || [ $c -gt 20 ]; thenecho "a 等于 10 并且 b 不等于 30,或者 c 大于 20"
fi
輸出:
a 等于 10 并且 b 不等于 30,或者 c 大于 20
通過使用這些邏輯運算符,可以在Shell腳本中對多個條件進行邏輯操作,根據不同的邏輯運算結果執行相應的操作。需要注意的是,在條件判斷語句中,邏輯運算符需要在方括號中使用,并且變量周圍需要有空格,以確保運算符正確解析。
3.1.4 字符串運算符
在Shell腳本中,字符串運算符用于對字符串進行操作,返回布爾值(真或假)。Shell提供了多種字符串運算符,包括 -n
、-z
、=~
、==
、!=
、<
、>
、-le
和 -ge
等。以下是關于Shell字符串運算符的詳細介紹以及相應的示例說明:
-n:非空
-n
用于判斷字符串是否為非空,如果非空則返回 true。
示例:
a="hello"
if [ -n $a ]; thenecho "a 不為空"
fi
輸出:
a 不為空
-z:空
-z
用于判斷字符串是否為空,如果為空則返回 true。
示例:
a=""
if [ -z $a ]; thenecho "a 為空"
fi
輸出:
a 為空
=~:匹配正則表達式
=~
用于匹配字符串與正則表達式,如果匹配成功則返回 true。
示例:
a="hello world"
if [[ $a =~ "world" ]]; thenecho "a 包含 world"
fi
輸出:
a 包含 world
==:等于
==
用于判斷兩個字符串是否相等,如果相等則返回 true。
示例:
a="hello"
b="hello"
if [ $a == $b ]; thenecho "a 等于 b"
fi
輸出:
a 等于 b
!=:不等于
!=
用于判斷兩個字符串是否不相等,如果不相等則返回 true。
示例:
a="hello"
b="world"
if [ $a != $b ]; thenecho "a 不等于 b"
fi
輸出:
a 不等于 b
<:小于
<
用于判斷一個字符串是否小于另一個字符串,如果是則返回 true。
示例:
a="apple"
b="banana"
if [ $a \< $b ]; thenecho "a 小于 b"
fi
輸出:
a 小于 b
>:大于
>
用于判斷一個字符串是否大于另一個字符串,如果是則返回 true。
示例:
a="banana"
b="apple"
if [ $a \> $b ]; thenecho "a 大于 b"
fi
輸出:
a 大于 b
-le:小于等于
-le
用于判斷一個字符串是否小于或等于另一個字符串,如果是則返回 true。
示例:
a="apple"
b="banana"
c="apple"
if [ $a \<= $b ] && [ $a -le $c ]; thenecho "a 小于等于 b,并且 a 小于等于 c"
fi
輸出:
a 小于等于 b,并且 a 小于等于 c
-ge:大于等于
-ge
用于判斷一個字符串是否大于或等于另一個字符串,如果是則返回 true。
示例:
a="banana"
b="apple"
c="banana"
if [ $a \>= $b ] && [ $a -ge $c ]; thenecho "a 大于等于 b,并且 a 大于等于 c"
fi
輸出:
a 大于等于 b,并且 a 大于等于 c
通過使用這些字符串運算符,可以在Shell腳本中對字符串進行條件判斷,根據不同的字符串運算結果執行相應的操作。需要注意的是,在條件判斷語句中,字符串運算符需要在方括號中使用,并且變量周圍需要有空格,以確保運算符正確解析。
3.1.5 文件測試運算符
Shell 提供了豐富的文件測試運算符,用于檢查文件的各種屬性。下面是對一些常用的文件測試運算符的詳細介紹以及相應的示例說明:
-e:文件存在
-e
用于檢查文件是否存在,如果文件存在則返回 true。
示例:
file="example.txt"
if [ -e $file ]; thenecho "$file 存在"
fi
輸出:
example.txt 存在
-f:普通文件
-f
用于檢查文件是否為普通文件,而不是目錄或設備文件等特殊類型的文件。如果是普通文件則返回 true。
示例:
file="example.txt"
if [ -f $file ]; thenecho "$file 是普通文件"
fi
輸出:
example.txt 是普通文件
-d:目錄
-d
用于檢查文件是否為目錄,如果是目錄則返回 true。
示例:
dir="example"
if [ -d $dir ]; thenecho "$dir 是目錄"
fi
輸出:
example 是目錄
-s:非空文件
-s
用于檢查文件是否為非空文件,如果文件大小大于0則返回 true。
示例:
file="example.txt"
if [ -s $file ]; thenecho "$file 是非空文件"
fi
輸出:
example.txt 是非空文件
-r:可讀
-r
用于檢查文件是否可讀,如果文件可讀則返回 true。
示例:
file="example.txt"
if [ -r $file ]; thenecho "$file 可讀"
fi
輸出:
example.txt 可讀
-w:可寫
-w
用于檢查文件是否可寫,如果文件可寫則返回 true。
示例:
file="example.txt"
if [ -w $file ]; thenecho "$file 可寫"
fi
輸出:
example.txt 可寫
-x:可執行
-x
用于檢查文件是否可執行,如果文件可執行則返回 true。
示例:
file="script.sh"
if [ -x $file ]; thenecho "$file 可執行"
fi
輸出:
script.sh 可執行
-nt 和 -ot:新于和舊于
-nt
用于檢查文件是否比另一個文件新,而 -ot
用于檢查文件是否比另一個文件舊。這兩個運算符可以用于比較文件的時間戳。
示例:
file1="file1.txt"
file2="file2.txt"
if [ $file1 -nt $file2 ]; thenecho "$file1 比 $file2 新"
fi
輸出:
file1.txt 比 file2.txt 新
通過使用這些文件測試運算符,可以在Shell腳本中輕松地檢查文件的存在性、類型、權限以及時間戳等屬性,從而根據文件的狀態執行相應的操作。這些運算符為Shell腳本編程提供了強大的文件操作能力。
3.2 test命令
test
命令是用于在Shell腳本中進行條件測試的工具,它也可以用方括號 [ ]
的形式來使用,因為test
其實就是方括號的另一種表示方式。test
命令接受不同的選項和參數,用于測試文件屬性、字符串比較、算術比較等,根據測試結果返回不同的退出狀態碼,以便在Shell腳本中進行條件判斷。
下面是test
命令的一些常用選項和示例說明:
-
測試文件屬性:
-
用法:
test -e file
-
描述:檢查文件是否存在。
-
示例:
file="example.txt" if test -e $file; thenecho "$file 存在" fi
-
-
字符串比較:
-
用法:
test string1 = string2
-
描述:檢查兩個字符串是否相等。
-
示例:
str1="hello" str2="world" if test $str1 = $str2; thenecho "兩個字符串相等" fi
-
-
整數比較:
-
用法:
test int1 -eq int2
-
描述:檢查兩個整數是否相等。
-
示例:
num1=10 num2=20 if test $num1 -eq $num2; thenecho "兩個整數相等" fi
-
-
文件比較:
-
用法:
test file1 -nt file2
和test file1 -ot file2
-
描述:
-nt
用于檢查文件1是否比文件2新,而-ot
用于檢查文件1是否比文件2舊。 -
示例:
file1="file1.txt" file2="file2.txt" if test $file1 -nt $file2; thenecho "$file1 比 $file2 新" fi
-
-
復合條件測試:
-
用法:
test condition1 -a condition2
和test condition1 -o condition2
-
描述:
-a
表示邏輯與(and),-o
表示邏輯或(or)。 -
示例:
num=15 if test $num -gt 10 -a $num -lt 20; thenecho "$num 大于10并且小于20" fi
-
除了直接使用test
命令以外,你也可以使用方括號的形式來進行條件測試,例如:
file="example.txt"
if [ -e $file ]; thenecho "$file 存在"
fi
無論是使用test
命令還是方括號形式,它們都能夠幫助你在Shell腳本中進行條件判斷,根據測試結果執行相應的操作。
3.3 Shell流程控制
Shell腳本中的流程控制可以幫助我們根據條件或循環來決定代碼的執行路徑。主要的流程控制結構包括條件語句(if-else)、循環語句(for、while、until)和跳轉語句(break、continue)等。
下面是對Shell的流程控制結構的詳細介紹以及相應的示例說明:
-
條件語句(if-else):
-
用法:
if condition; then# 條件為真時執行的代碼塊 else# 條件為假時執行的代碼塊 fi
-
描述:根據給定的條件判斷,決定執行哪個代碼塊。
-
示例:
num=10 if [ $num -gt 0 ]; thenecho "數字大于0" elseecho "數字小于等于0" fi
-
-
循環語句(for):
-
用法:
for var in list; do# 循環體內執行的代碼塊 done
-
描述:遍歷列表中的元素,每次迭代將列表中的一個元素賦值給變量,并執行對應代碼塊。
-
示例:
fruits=("apple" "banana" "orange") for fruit in ${fruits[@]}; doecho "水果:$fruit" done
-
-
多選擇語句(case):
-
用法:
case value inpattern1)# 匹配模式1時執行的代碼塊;;pattern2)# 匹配模式2時執行的代碼塊;;pattern3|pattern4)# 匹配模式3或模式4時執行的代碼塊;;*)# 以上模式都不匹配時執行的代碼塊;; esac
-
case 語句為多選擇語句。可以用case語句匹配一個值與一個模式,如果匹配成功,執行相匹配的命令。
-
示例:
#!/bin/bashfruit="apple" case $fruit in"apple")echo "Selected fruit is Apple";;"banana")echo "Selected fruit is Banana";;"orange"|"kiwi")echo "Selected fruit is Orange or Kiwi";;*)echo "Unknown fruit";; esac
-
-
循環語句(while):
-
用法:
while condition; do# 循環體內執行的代碼塊 done
-
描述:只要條件為真,就會一直執行循環體內的代碼塊。
-
示例:
num=1 while [ $num -le 5 ]; doecho "當前數字:$num"num=$((num + 1)) done
-
-
循環語句(until):
-
用法:
until condition; do# 循環體內執行的代碼塊 done
-
描述:只要條件為假,就會一直執行循環體內的代碼塊。
-
示例:
num=1 until [ $num -gt 5 ]; doecho "當前數字:$num"num=$((num + 1)) done
-
-
跳轉語句(break):
-
用法:
break
-
描述:跳出當前循環或選擇結構,繼續執行循環或選擇結構之后的代碼。
-
示例:
for num in 1 2 3 4 5; doif [ $num -eq 3 ]; thenbreakfiecho "當前數字:$num" done
-
-
跳轉語句(continue):
-
用法:
continue
-
描述:跳過當前循環中余下的代碼,進入下一次循環迭代。
-
示例:
for num in 1 2 3 4 5; doif [ $num -eq 3 ]; thencontinuefiecho "當前數字:$num" done
-
通過使用這些流程控制結構,你可以根據條件或循環來控制Shell腳本中的代碼執行。這些結構提供了靈活性和可擴展性,使得Shell腳本能夠處理各種不同的情況和需求。
3.4 Shell函數
在Shell腳本編程中,函數是一種重要的流程控制結構,用于封裝一段可重復使用的代碼塊。通過定義函數,你可以將一組相關的操作組合在一起,并在需要時調用它們。下面是對Shell的流程控制函數的詳細介紹以及相應的示例說明:
1. 定義函數:
function_name() {# 函數體內執行的代碼塊# 可以包含變量、命令、流程控制語句等
}
或者
function function_name {# 函數體內執行的代碼塊# 可以包含變量、命令、流程控制語句等
}
2. 調用函數:
function_name
3. 函數的示例說明:
#!/bin/bash# 定義一個簡單的函數
say_hello() {echo "Hello, World!"
}# 調用函數
say_hello
在上面的示例中,我們定義了一個名為say_hello
的函數,它的功能是輸出"Hello, World!"。然后,我們通過調用say_hello
函數來執行這段代碼。
函數還可以接受參數,允許你向函數傳遞數據。下面是一個帶有參數的函數的示例:
#!/bin/bash# 定義一個帶有參數的函數
greet() {name=$1echo "Hello, $name!"
}# 調用函數,并傳遞參數
greet "Alice"
在上面的示例中,我們定義了一個名為greet
的函數,它接受一個參數name
。函數體內將參數賦值給變量name
,然后輸出"Hello, $name!“。通過調用greet
函數并傳遞參數"Alice”,我們可以輸出"Hello, Alice!"。
函數還可以返回值,在Shell腳本中使用return
語句來實現。下面是一個帶有返回值的函數的示例:
#!/bin/bash# 定義一個帶有返回值的函數
add_numbers() {num1=$1num2=$2sum=$(($num1 + $num2))return $sum
}# 調用函數,并接收返回值
result=$(add_numbers 10 20)
echo "Sum: $result"
在上面的示例中,我們定義了一個名為add_numbers
的函數,它接受兩個參數num1
和num2
,計算它們的和并將結果賦給變量sum
。然后,我們使用return
語句返回sum
的值。通過調用add_numbers
函數并將返回值賦給變量result
,我們可以輸出"Sum: 30"。
通過使用函數,你可以將一段代碼封裝起來,提高代碼的可重用性和可維護性。函數可以接受參數、返回值,并且可以包含變量、命令、流程控制語句等,讓你的Shell腳本更加靈活和功能強大。
4. Shell腳本必須以.sh后綴結尾嗎
不是必須的,可以不加.sh。但擴展名sh代表shell,可以讓人看到后綴就知道是shell腳本,是一種命名規范,所以建議加上。
在Linux中,腳本的后綴并不影響其是否可以執行。Shell腳本的可執行性是根據文件的權限屬性來確定的。