Bash

如何在 bash 腳本中將普通參數與標記參數混合?

  • September 11, 2022

例如,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

根據您對輸入非選項參數的順序的擔憂,您的腳本需要嚴格的順序,您的使用者必須遵循(否則他們會收到錯誤),或者您的腳本不需要特定的順序,並且必須使用其他解析方法來弄清楚如何使用它們。

但在我看來,無序參數是我們有選項字母的原因。其餘參數是有序的,否則它們將具有選項字母。不過,這只是我的看法。

引用自:https://unix.stackexchange.com/questions/716777