私は最大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
)
答え2
私はwhile / shiftループを使っていました。
#! /bin/bash
PROGNAME=$(basename $0)
while [ -n "$1" ]
do
echo "OPT: $1"
case "$1" in
--user=* )
if [[ "$1" =~ --user=(.+) ]]
then
USER=${BASH_REMATCH[1]}
else
echo "$PROGNAME: option requires an argument -- $1"
exit 2
fi
;;
-u )
if [ -z "$2" ]
then
echo "$PROGNAME: option requires an argument -- $1"
exit 2
fi
USER="$2"
shift
;;
* )
echo "$PROGNAME: illigal option or argument -- $1"
exit 1
;;
esac
shift
done
[ -n "$USER" ] && echo "USER: $USER"
echo "GOOD"
しかし、$USER
すでに設定されているので悪い変数です。