Bash Shell 指令碼/位置引數
在上面大多數命令中——無論是執行內建命令,還是使用外部程式——我們都提供了一個或多個 *引數*,這些引數指示命令應該對什麼進行操作。例如,當我們呼叫常見的 Unix 工具 mkdir(“建立目錄”)來建立一個新目錄時,我們使用類似於以下的命令呼叫它
mkdir tmp
其中 tmp 是要建立的新目錄的名稱。
正如我們所見,Bash 指令碼本身也是可以執行的程式。因此,它們也可以接受引數。這些引數作為指令碼的 *位置引數* 提供給程式。之前,我們瞭解到變數是一種引數。位置引數非常相似,但由數字而不是名稱標識。例如,$1(或 ${1})擴充套件為指令碼的第一個引數。因此,假設我們想建立一個名為 mkfile.sh 的簡單指令碼,它接受兩個引數——一個檔名和一行文字——並使用指定的文字建立指定的 檔案。我們可以按如下方式編寫它
#!/bin/bash
echo "$2" > "$1"
(注意檔案開頭處的 #!/bin/bash 行;我們在 基本命令 中介紹了該行。當你執行此程式碼時,該行將保證它被 Bash shell 解釋,即使你是從另一個程式執行或你的計算機具有非標準配置。)
透過執行 chmod +x mkfile.sh 使其可執行後,我們可以按如下方式執行它
./mkfile.sh file-to-create.txt 'line to put in file'
我們也可以透過使用 $@ 來一次性引用所有引數,它擴充套件為 *所有* 位置引數,按順序排列。當用雙引號括起來時,如 "$@",每個引數都成為一個獨立的詞語。(注意:$* 可能是更常見的替代方案,但 "$*" 成為單個詞語,原始引數之間用空格隔開。"$@" 幾乎總是比 $@ 或 $* 更可取,$@ 和 $* 允許包含空格的引數被拆分為多個詞語,而 "$*" 將多個引數合併為單個詞語。)這通常與內建命令 shift 結合使用非常有用,shift 會移除第一個位置引數,這樣 $2 就變成 $1,$3 就變成 $2,依此類推。例如,如果我們將 mkfile.sh 更改為以下內容
#!/bin/bash
file="$1" # save the first argument as "$file"
shift # drop the first argument from "$@"
echo "$@" > "$file" # write the remaining arguments to "$file"
然後我們可以按如下方式執行它
./mkfile.sh file-to-create.txt line to put in file
所有引數(檔名除外)將被寫入檔案。
位置引數的數量可以透過 $# 獲取;例如,如果 $# 為 3,則位置引數為 $1、$2 和 $3。
注意,超過 $9 的位置引數需要使用花括號;如果你需要引用第十個引數,例如,你必須寫 ${10} 而不是 $10。(後者將被解釋為 ${1}0。)也就是說,通常不建議使用太多具有特定含義的引數,因為使用者很難跟蹤它們。如果你發現自己專門引用指令碼的第十個引數,可能需要重新評估你的方法。
如果你有一些使用 Bash 或 Unix 工具的經驗,你可能已經注意到,許多命令除了普通引數之外,還可以接受以連字元 - 開頭的各種“選項”。例如,rm "$filename" 刪除單個檔案,而 rm -r "$dirname" 刪除整個目錄及其所有內容。(-r 代表“遞迴”:該命令“遞迴”地刪除整個目錄樹。)這些選項實際上只是引數。在 rm "$filename" 中,只有一個引數("$filename"),而在 rm -r "$dirname" 中,有兩個引數(-r 和 "$dirname")。從某種意義上說,這些引數本身並沒有什麼特別之處,但這種選項表示法非常普遍,以至於被認為是標準;許多或大多數 Bash 內建命令都可以接受各種選項,稍後我們將看到支援選項作為 Bash 指令碼引數的各種技術。