オプションを含むシェルスクリプト

オプションを含むシェルスクリプト

私は最大2つのオプションを許可するシェルスクリプトを書いています。しかし、問題があります。助けてください? (スクリプト名が仮定されますcommand。)

#!/bin/bash
PROGNAME=$(basename $0)
for OPT in "$@"
do
    echo "OPT: $OPT"
    case "$OPT" in
            '-p' | '--password' )
                    if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]]
                    then
                            echo "$PROGNAME: option requires an argument -- '$(echo $1 | sed 's/^-*//')'"
                            exit 2
                    fi
                    PASSWORD="$2"
                    shift 2
                    ;;
            '-u' | '--user' )
                    if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]]
                    then
                            echo "$PROGNAME: option requires an argument -- '$(echo $1 | sed 's/^-*//')'"
                            exit 2
                    fi
                    USER="$2"
                    shift 2
                    ;;
            * )
                    echo "$1"
                    echo "$PROGNAME: illigal option or argument -- '$(echo $1 | sed 's/^-*//')'"
                    exit 1
                    ;;
    esac
done
echo "GOOD"

テスト1

$./command 
GOOD

テスト2

$./command -u user
OPT: -u
OPT: user

command: illigal option or argument -- ''

(4行目は空です。)

テスト3

$./command -u user -p passwd
OPT: -u
OPT: user
-p
command: illigal option or argument -- 'p'

-u、--user、-p、および--passwordでも同様です。 3つの質問があります。

1)test2、test3に「OPT:user」が表示されるのはなぜですか?

2)このコードにオプションを与えると、なぜエラーが発生しますか?

3) このコードをどのように修正しますか?あなたの助けに感謝します!

ベストアンサー1

拡張は"$@"ループの開始時に発生します。for内部的にはshift何の影響もありません。

例えば

for a in "$@"
do
  echo OPTION: $a
  shift 2
done

これで:

$ bash x a b c d e f
OPTION: a
OPTION: b
OPTION: c
OPTION: d
OPTION: e
OPTION: f

shift何もなされていないことがわかります

代わりに毎回再評価したいです。

$ cat x             
while [ $# -gt 0 ]
do
  a="$1"
  echo OPTION: $a
  shift 2
done

$ bash x a b c d e f
OPTION: a
OPTION: c
OPTION: e

(これより良いテストを実行する必要があります。奇数の引数を渡すと、このサンプルコードは失敗するため終了しません。shift 2

おすすめ記事