%20%E5%92%8C%E9%9B%99%E7%AD%89%E8%99%9F%20(%3D)%20%E6%9C%89%E4%BD%95%E4%B8%8D%E5%90%8C%EF%BC%9F.png)
請閱讀,為了比較內部的字串,if
我們需要使用雙方括號。有的書上說可以透過 來比較=
。但它==
也適用於。
#!/bin/bash
a="hello"
b="world"
if [[ $a == $b ]];then
echo "equal"
fi
=
和==
比較有差嗎?
答案1
在bash
(就像從ksh
哪裡bash
複製該語法一樣),[[ $a == $b ]]
不是比較,而是模式匹配。您需要[[ $a == "$b" ]]
進行位元組到位元組的相等比較。=
與==
任何支援[[...]]
.
[[...]]
不是標準sh
語法。這[
命令是標準,且標準比較存在運算符=
(儘管某些[
實作也可以識別==
1)。
就像任何命令的任何參數一樣,必須引用變數擴展以防止分割+全域和空刪除(僅後者在 中執行zsh
),所以:
[ "$a" = "$b" ]
在標準中sh
,模式匹配是透過以下方式完成的case
:
case $a in
($b) ...
esac
為了完整起見,其他類似平等的您可能在 shell 腳本中遇到的運算子:
[ "$a" -eq "$b" ]
:[
比較十進制整數的標準運算子。有些[
實作允許數字周圍有空格,有些允許任意算術表達式,但這不可移植。可移植地,人們可以使用[ "$(($a))" -eq "$(($b))" ]
它。另請參閱[ "$((a == b))" -ne 0 ]
以下標準等效項(POSIXly 除外,僅當$a
和$b
包含整數常數時才指定行為):((a == b))
,來自 ksh,也可在zsh
和中找到bash
,如果儲存在中的算術表達式的計算結果$a
與 的結果相同,則傳回 true$b
。通常,它用於比較數字。請注意,shell 之間在如何計算算術表達式以及支援哪些數字方面存在差異(例如 bash 和 ksh 的某些實作/版本不支援浮點或將帶前導零的數字視為八進位)。expr "$a" = "$b"
如果兩個運算元都被辨識為十進位整數(有些允許數字周圍有空格),則進行數字比較,否則檢查兩個字串運算元是否具有相同的排序順序。對於$a
或$b
等expr
運算符的值也會失敗(
,substr
...awk -- 'BEGIN{exit !(ARGV[1] == ARGV[2])}' "$a" "$b"
:如果$a
和$b
被識別為數字(至少是十進制整數和浮點數,如 1.2、-1.5e-4,忽略前導尾隨空格,有些還識別十六進制、八進位或 識別的任何數字strtod()
),則執行數字比較。否則,根據實現的不同,它要么是字節到字節的字串比較,要么是類似的expr
比較strcoll()
,即$a
和$b
排序是否相同。
也可以看看:
1 包括 GNU[
和, ,[
的內建函數,雖然不是全部基於 shell 和,但請注意,ksh
bash
yash
ash
zsh
zsh
=cmd
是一個特殊的檔案名稱擴充運算符(在相同的上下文中擴展~user
)擴展為相應命令的路徑,因此,除非您關閉equals
禁用該功能的選項,否則您需要編寫它[ "$a" '==' "$b" ]
,否則您會收到錯誤,該=
命令沒有找到。同樣適用於[ "$string" '=~' "$regexp" ]
答案2
這些在 bash 中是等效的:
[[ $x == "$y" ]]
[[ $x = "$y" ]]
[ "$x" == "$y" ]
[ "$x" = "$y" ]
前兩個 $x 變數不必加引號。 Bash 在 [ 內執行分詞和路徑名擴展,但不在 [[ 內執行:
$ x='a b'
$ [ -s $x ]
-bash: [: a: binary operator expected
$ [[ -s $x ]]
$ ls
$ [ a = * ]
-bash: [: a: unary operator expected
$ [[ a = * ]]
$
[[ $x = "$y" ]]
是字串比較,但是[[ $x = $y ]]
是模式比對表達式:
$ y='a*'; [[ aa = "$y" ]]; echo $?
1
$ y='a*'; [[ aa = $y ]]; echo $?
0
-eq 僅適用於整數:
$ [[ x.x -eq x.x ]]
-bash: [[: x.x: syntax error: invalid arithmetic operator (error token is ".x")
$ x=9; [[ "x" -eq 9 ]]; echo $?
0
答案3
和=
都是==
運算符。在某些語言(如 C)中,一種用於為變數賦值,另一種用於比較值(算術表達式的結果)。事實上,這兩個運算子正是算術求值中的運算子。 A$((a=23))
是賦值,a$((a==23))
是算術比較。
$ echo "$((a=11)) $((a==23))" "$((a=23))" "$((a==23))"
11 0 23 1
但在測試結構內部(所有測試和[…]和[[…]]) 兩個運算子的意思相同並執行相同的操作。
所以,所有這些選項:
test "$a" = "$b"
[ "$a" = "$b" ]
[[ "$a" = "$b" ]]
test "$a" == "$b"
[ "$a" == "$b" ]
[[ "$a" == "$b" ]]
是內部等效巴什測試二進制相等(引用的變數)。如果正確的變數未加引號,則它可能會被解釋為模式並進行相應的匹配:作為模式而不是文字字串。
帶有引號的運算子\=
和\==
在 test 和 中使用時也是等效的[…]
。但引用的運算符\==
在內部失敗[[…]]
。
對於其他 shell,結果各不相同(正確的結果應該是Y -
(true false),不同於 0 (true) 和 1 (false) 的退出代碼將報告為失敗¤
)。某些 shell 會失敗- -
(退出程式碼始終為 1)。
| dash ksh bash zsh
test a = "$b" | Y - Y - Y - Y -
[ a = "$b" ] | Y - Y - Y - Y -
[[ a = "$b" ]] | ¤ ¤ Y - Y - Y -
test a == "$b" | ¤ ¤ Y - Y - - -
[ a == "$b" ] | ¤ ¤ Y - Y - - -
[[ a == "$b" ]] | ¤ ¤ Y - Y - Y -
test a \= "$b" | Y - Y - Y - Y -
[ a \= "$b" ] | Y - Y - Y - Y -
[[ a \= "$b" ]] | ¤ ¤ Y - - - - -
test a \== "$b" | ¤ ¤ Y - Y - Y -
[ a \== "$b" ] | ¤ ¤ Y - Y - Y -
[[ a \== "$b" ]] | ¤ ¤ Y - - - - -
所有選項都可以在 ksh 中使用,帶引號的運算子在 bash 和 zsh(在 內部[[…]]
)中失敗,而未加引號的運算\=
子\==
在 zsh(在 外部[[…]]
)中也失敗。