Posix
是否所有 POSIX shell 都以相同的方式實現算術擴展 $((…)) ?
我正在嘗試編寫一個可以在任何 POSIX shell 下工作的 shell 腳本,我發現
dash
. 我想知道這是否是我可以依賴於在其他 POSIX 兼容的 shell 下工作的東西,或者它是否只是dash
shell 的一個無意的特性。在算術擴展中,變數可以寫成帶或不帶初始美元符號(位置參數的情況除外,它必須始終寫成美元符號
$1
等$2
)。但是我發現 的行為
"$((X))"
不同於"$(($X))"
似乎"$(($X))"
被擴展了兩次,而不僅僅是一次。即,如果我的變數X
包含另一個變數的名稱(X=Y
),而該變數又包含一個數值 (Y=1
),那麼"$(($X))"
將返回1
,而"$((X))"
只會產生一個“非法數字:Y”錯誤。我可以依賴其他 POSIX shell 中的這種行為嗎?
奇怪的行為
"$((X))"
並且"$(($X))"
行為不一樣。$ X=Y; Y=1 $ echo "$((X))" dash: 1: Illegal number: Y $ echo "$(($X))" 1
預期行為
為了完整起見,我在這裡包括沒有間接和兩層間接的內容。沒有間接,一切都按預期工作:
$ X=1 $ echo "$((X))" 1 $ echo "$(($X))" 1
正如預期的那樣,兩層間接不起作用(儘管請注意錯誤消息指的是不同的值)。
$ X=Y; Y=Z; Z=1 $ echo "$((X))" dash: 6: Illegal number: Y $ echo "$(($X))" dash: 7: Illegal number: Z
這個問題與這個關於算術擴展和參數擴展的問題有些相關,但它不一樣,因為它處理的是
bash
更高級的 shell 的行為,但我想知道預期的 POSIX 行為。
由於您的問題是 POSIX 通用的,並且相關問題似乎涉及更高級的 shell,我將單獨回答這個問題。
您看到的行為來自兩種不同的擴展,參數擴展和算術擴展,POSIX 以該順序指定。和
$ X=Y; Y=1
您的第一個範例僅使用算術擴展:
$ echo "$((X))"
試圖將
X
的值解釋為算術表達式,但失敗了,因為“Y”不是數字。您的第二個範例同時使用:
$ echo "$(($X))"
展開(參數展開)為
$ echo "((Y))"
然後算術擴展使用
Y
’ 值 1。另請參閱了解在算術表達式和Bash中使用間接擴展進行變數擴展的兩個範例:算術擴展、參數擴展和逗號運算符等。