如何在 bash 腳本中將普通參數與標記參數混合?
例如,gcc 接受沒有任何標誌的輸入文件和帶有
-o
標誌的輸出文件:
gcc input.c -o output.out
或者
gcc -o output.out input.c
我正在創建一個隨機密碼生成器 bash 腳本,使用者應該能夠分別使用
-s
,-l
,-u
標誌指定特殊字元、小寫字元和大寫字元的數量。他們還應該能夠在沒有任何標誌的情況下指定密碼的長度。範例用法:
./randompassword.sh -s2 -u2 -l3 16
應該是一個包含 2 個特殊字元、2 個大寫字元、3 個小寫字元且長度為 16 的密碼。
我可以
getopts
像這樣解析標誌:while getopts s:l:u: flag do case "${flag}" in s) special=${OPTARG};; l) lower=${OPTARG};; u) upper=${OPTARG};; esac done
但是我不知道如何獲得沒有標誌的長度參數。
我嘗試使用
$1
,但這個參數應該能夠在命令中的任何位置,就像 gcc 範例一樣。
getopts
一旦到達非選項參數,就停止解析參數列表。也就是說,它在從左到右迭代選項參數時返回成功,然後在第一個非選項上返回失敗。所以正確的案例是put options and their arguments on the command line before any non-option arguments
.
getops
教程然後顯示一個命令shift $((OPTIND - 1))
。while
循環遍歷選項參數,然後將shift
它們從位置變數中刪除,將非選項參數(如果有)留在$@
.在程式碼中,使用教程中的變數:
while getopts ':s:l:u:' OPTION do case "${OPTION}" in s) special=${OPTARG};; l) lower=${OPTARG};; u) upper=${OPTARG};; \?) echo "$0: Error: Invalid option: -${OPTARG}" >&2; exit 1;; :) echo "$0: Error: option -${OPTARG} requires an argument" >&2; exit 1;; esac done shift $((OPTIND - 1)) # now the positional variables have the non-option arguments echo "${1}"
使用您的範例命令 (
./randompassword.sh -s2 -u2 -l3 16
),輸出為16
.我在 getopts 字元串中添加了一個前導
:
,因為它為您提供“靜默錯誤報告”,這讓您的腳本可以擷取錯誤並發出更友好的投訴。這就是我添加到case
語句中的額外兩個選項的功能。如果使用者違反規則並在非選項參數之後
while
鍵入選項參數,則在上面的循環中將不會解析尾隨選項參數。它/它們將出現在$@
包含剩餘位置參數的數組中。如果使用者遵循指南並在非選項參數之前鍵入所有選項參數,則數組將在循環和命令完成$@
後具有非選項參數。while``shift
根據您對輸入非選項參數的順序的擔憂,您的腳本需要嚴格的順序,您的使用者必須遵循(否則他們會收到錯誤),或者您的腳本不需要特定的順序,並且必須使用其他解析方法來弄清楚如何使用它們。
但在我看來,無序參數是我們有選項字母的原因。其餘參數是有序的,否則它們將具有選項字母。不過,這只是我的看法。