「--」の後に認識できないオプションを残して、Bashスクリプトでオプションを解析する方法は?

「--」の後に認識できないオプションを残して、Bashスクリプトでオプションを解析する方法は?

Bashスクリプトでオプションの解析を実行する方法を探しています(たとえば、短いパラメータと長いパラメータの両方を許可します)。選択項目のインポート実際には)認識できない最初の引数で解析を停止し、-認識できない最初のパラメータの前に、残りのパラメータを出力文字列にコピーします。

たとえば、私が望む動作は次のとおりです。

% OPTIONS=("-u" "name1" "--username=name2" "-x" "a" -u "b" "c")
% getopt -o u: -l username: -n programname -- "${OPTIONS[@]}"
-u 'name1' --username 'name2' -- -x 'a' -u 'b' 'c'
%

getoptユーティリティはこのように動作せず、代わりに次のものをエクスポートします。

programname: invalid option -- 'x'
-u 'name1' --username 'name2' -u 'b' -- 'a' 'c'

上記の2番目の項目に示されているように、認識できないオプションの後に続く引数が認識されたように並べ替えられたくありません。- ゆうオプション。誰かが上記の最初のコードブロックで説明した結果を提供するソリューションを見つけることができることを願っています。どんなアイデアがありますか?

環境:バッシュ4.2.46(1)、CentOS 7.2 @ 3.10.0-327.36.1.el7.x86_64。

必要:CentOS 7.2 Minimal、他のソフトウェアをインストールする必要はなく、すべてのコードはBashスクリプトで書かれています。オプションパーサーに渡されるオプションには、以下を含める必要はありません。-(つまり、解析の終了は自動的に行われるべきです)

ベストアンサー1

この問題を解決するには別のものが必要です選択項目のインポートなぜなら選択項目のインポート再配置すると、オプションの仕様と一致するオプションが見つかり、認識できないオプションでは終了します。バッシュ内蔵選択項目のインポート救助に来てください。ただし、長期的なオプションを処理できるはずです。投稿にArvid RequateとTomRoche、作れる「トリック」があります。選択項目のインポート長いオプションを処理するには、以下を使用してください。-オプション仕様として使用し、オプション仕様の前にコロンを使用してエラー報告を削除します。ただし、このソリューションでは、短いオプションと長いオプションを処理するためにコードの重複が必要です。

以下は私がテストしたソリューションで、すべての要件を満たし、短いオプションと長いオプションを重複するわけではありません。明確さと完全性のために私は変更しましたユーザー名到着置くそして追加されましたスイッチ価値のないオプションを表示します。

パーサー

#!/bin/bash

Options=("$@")
while getopts ":s:-:" OptChar "${Options[@]}"; do
   case "$OptChar" in
    -)   case "$OPTARG" in
         set|set=*)
            if [[ $OPTARG =~ ^set= ]] ; then
               Value="${Options[$OPTIND-2]#*=}"
            else
               Value="${Options[$OPTIND-1]}"
               ((OPTIND++))
            fi
            echo "Parsed: --$OPTARG, value: '$Value'"
            ;;

         toggle)
            echo "Parsed: --$OPTARG";;
         *) ((OPTIND--)); break;;
         esac
         ;;

   # Redirect short arguments to long arguments
   s)    ((OPTIND-=2)); Options[OPTIND-1]="--set";;
   t)    ((OPTIND--)); Options[OPTIND-1]="--toggle";;

   *)    ((OPTIND--)); break;;
   esac
done
Options=( "${Options[@]:$OPTIND-1}" )

echo "REMAINING Options: ${Options[@]}"

これは私のテストコードです。

% ./parse.sh --set=a  -s b --set= --set c --unknown -s d --set e
Parsed: --set=a, value: 'a'
Parsed: --set, value: 'b'
Parsed: --set=, value: ''
Parsed: --set, value: 'c'
REMAINING Options: --unknown -s d --set e
%
% ./parse.sh -s a -x -s b
Parsed: --set, value: 'a'
REMAINING Options: -x -s b
%

おすすめ記事