在編寫 linux bash shell 腳本時,經常會用到 $0、$1、$2、$#、$@、$*、$? 等參數,下面具體說明這些參數的含義。
假設執行 ./test.sh a b c 這樣一個命令,則可以使用下面的參數來獲取一些值:
- $0 對應 "./test.sh" 這個值。如果執行的是 ./work/test.sh, 則對應 ./work/test.sh 這個值,而不是只返回文件名本身的部分。
- $1 會獲取到 a,即 $1 對應傳給腳本的第一個參數。
- $2 會獲取到 b,即 $2 對應傳給腳本的第二個參數。
- $3 會獲取到 c,即 $3 對應傳給腳本的第三個參數。$4、$5 等參數的含義依此類推。
- $# 會獲取到 3,對應傳入腳本的參數個數,統計的參數不包括 $0。
- $@ 會獲取到 "a" "b" "c",也就是所有參數的列表,不包括 $0。
- $* 也會獲取到 "a" "b" "c", 其值和 $@ 相同。但 "$*" 和 "$@" 有所不同。"$*" 把所有參數合并成一個字符串,而 "$@" 會得到一個字符串參數數組。
- $? 可以獲取到執行 ./test.sh a b c 命令后的返回值。在執行一個前臺命令后,可以立即用 $? 獲取到該命令的返回值。該命令可以是系統自身的命令,可以是 shell 腳本,也可以是自定義的 bash 函數。
當執行系統自身的命令時,$? 對應這個命令的返回值。
當執行 shell 腳本時,$? 對應該腳本調用 exit 命令返回的值。如果沒有主動調用 exit 命令,默認返回為 0。
當執行自定義的 bash 函數時,$? 對應該函數調用 return 命令返回的值。如果沒有主動調用 return 命令,默認返回為 0。
下面舉例說明 "$*" 和 "$@" 的差異。假設有一個 testparams.sh 腳本,內容如下:
#!/bin/bash for arg in "$*"; do echo "****:" $arg done echo -------------- for arg in "$@"; do echo "@@@@:" $arg done
這個腳本分別遍歷 "$*" 和 "$@" 擴展后的內容,并打印出來。執行 ./testparams.sh,結果如下:
$ ./testparams.sh This is a test ****: This is a test -------------- @@@@: This @@@@: is @@@@: a @@@@: test
可以看到,"$*" 只產生一個字符串,for 循環只遍歷一次。
而 "$@" 產生了多個字符串,for 循環遍歷多次,是一個字符串參數數組。
注意:如果傳入的參數多于 9 個,則不能使用 $10 來引用第 10 個參數,而是要用 ${10} 來引用。即,需要用大括號{}把大于 9 的數字括起來。
例如,${10} 表示獲取第 10 個參數的值,寫為 $10 獲取不到第 10 個參數的值。實際上,$10 相當于 ${1}0,也就是先獲取 $1 的值,后面再跟上 0,如果 $1 的值是 "first",則 $10 的值是 "first0"。
查看 man bash 里面對位置參數(positional parameters)的說明如下:
Positional Parameters
A positional parameter is a parameter denoted by one or more digits, other than the single digit 0.Positional parameters are assigned from the shell's arguments when it is invoked, and may be reassigned using the set builtin command. Positional parameters may not be assigned to with assignment statements. The positional parameters are temporarily replaced when a shell function is executed.
When a positional parameter consisting of more than a single digit is expanded, it must be enclosed in braces.
即,最后一句提到,當位置參數由多位數字組成時,需要用大括號 {} 把多位數字括起來。
獲取位置參數的個數
在 bash 中,可以使用 $# 來獲取傳入的命令行或者傳入函數的參數個數。
要注意的是,$# 統計的參數個數不包括腳本自身名稱或者函數名稱。
例如,執行 ./a.sh a b,則 $# 是 2,而不是 3。
查看 man bash 的說明如下:
Special Parameters
# Expands to the number of positional parameters in decimal.
可以看到,$# 實際上是擴展為位置參數(positional parameters)的個數,統計的參數不包括 $0。