雙括號((...))
是arithmetic expansion,而單括號(...)
運行在一個subshell封閉命令,它有自己的範圍,並且不影響它的父殼的環境。
這裏,(res = $1 + $2)
,即使變量res
成功分配到子shell的值,res
留在母貝,這就解釋了爲什麼沒有獲取打印取消設置。在這種情況下,您想使用((...))
。
此外,請注意,在您的示例中,第二個參數$2
是運算符,而不是第二個操作數。因此,您需要使用((res = $1 + $3))
和((res = $1 - $3))
。
此外,對於穩健性,您可能希望確保
- 參數的數目是有效的,
- 第一和第三個參數是有效的整數,
- 第二個參數是一個有效的算術運算器(
+
或-
,這裏),
- 等
最後,爲了改進跨不同殼體的可移植性,優選printf
優於echo
。
修正和改進代碼
#!/bin/sh
# foo
# Custom error function
die() {
printf "%s\n" "$1" 1>&2 ;
exit 1;
}
# Function that returns an exit status of
# 0 if its first argument is a valid integer,
# 1 otherwise.
is_integer() {
[ "$1" -eq 0 -o "$1" -ne 0 ] >/dev/null 2>&1
}
# Check that the number of argument is 3
[ "$#" -eq 3 ] || die "invalid number of arguments"
# Check that the operands are valid integers
is_integer "$1" || die "invalid first operand"
is_integer "$3" || die "invalid second operand"
# If the second argument is a valid operator, assign res accordingly;
# otherwise, die.
case "$2" in
'+')
((res = $1 + $3))
;;
'-')
((res = $1 - $3))
;;
*)
die "invalid operator"
;;
esac
printf "%s\n" "$res"
測試
使得腳本後(所謂的 「富」)的可執行文件,運行
chmod u+x foo
我得到下面的結果
$ ./foo -18 + 5
-13
$ ./foo 9 - 4
5
$ ./foo a + 2
invalid first operand
$ ./foo -18 + c
invalid second operand
$ ./foo 3/4
invalid operator
你是哪個外殼使用? – melpomene
'((...))'用於[算術擴展](http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_04),而'(...)'運行封裝在子shell中的命令,它不影響它的父shell。 – Jubobs
此外,請注意,在您的示例中,第二個參數('$ 2')是操作符,而不是第二個操作數。因此,你可能需要'((res = $ 1 + $ 3))'和'((res = $ 1 - $ 3))',這裏。 – Jubobs