さまざまなオプションを受け入れるシェルスクリプトを構築しようとしgetopts
ています。オプションと引数の変数の順序を処理できるため、良い解決策のようです(私はそう思います!)。
私は短いオプションのみを使用し、各短いオプションには対応する値が必要です。例:./command.sh -a arga -g argg -b argb
ほとんどの人がシェルコマンドでの作業に慣れているように、オプションを特定の順序で入力できないようにしたい。
もう1つのポイントは、オプションの引数値のチェックを自分自身で、理想的にはcase
ステートメント内で行いたいということです。その理由は:)
、私のcase
声明での私のテストで一貫性のない結果が得られたためです(おそらく私の理解が不足しているためです)。
例えば:
#!/bin/bash
OPTIND=1 # Reset if getopts used previously
if (($# == 0)); then
echo "Usage"
exit 2
fi
while getopts ":h:u:p:d:" opt; do
case "$opt" in
h)
MYSQL_HOST=$OPTARG
;;
u)
MYSQL_USER=$OPTARG
;;
p)
MYSQL_PASS=$OPTARG
;;
d)
BACKUP_DIR=$OPTARG
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 2;;
:)
echo "Option -$OPTARG requires an argument" >&2
exit 2;;
esac
done
shift $((OPTIND-1))
echo "MYSQL_HOST='$MYSQL_HOST' MYSQL_USER='$MYSQL_USER' MYSQL_PASS='$MYSQL_PASS' BACKUP_DIR='$BACKUP_DIR' Additionals: $@"
このような発生で失敗しました... ./command.sh -d -h
-dに引数が必要なフラグを付けたいのですが、その値が-d=-h
必要なものではありません。
したがって、caseステートメント内で独自の検証を実行して、各オプションが設定され、1回だけ設定されるようにする方が簡単だと考えました。
以下を実行しようとしていますが、if [ ! "$MYSQL_HOST" ]; then
ブロックがトリガーされません。
OPTIND=1 # Reset if getopts used previously
if (($# == 0)); then
echo "Usage"
exit 2
fi
while getopts ":h:u:p:d:" opt; do
case "$opt" in
h)
MYSQL_HOST=$OPTARG
if [ ! "$MYSQL_HOST" ]; then
echo "host not set"
exit 2
fi
;;
u)
MYSQL_USER=$OPTARG
if [ ! "$MYSQL_USER" ]; then
echo "username not set"
exit 2
fi
;;
p)
MYSQL_PASS=$OPTARG
if [ ! "$MYSQL_PASS" ]; then
echo "password not set"
exit 2
fi
;;
d)
BACKUP_DIR=$OPTARG
if [ ! "$BACKUP_DIR" ]; then
echo "backup dir not set"
exit 2
fi
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 2;;
#:)
# echo "Option -$opt requires an argument" >&2
# exit 2;;
esac
done
shift $((OPTIND-1))
echo "MYSQL_HOST='$MYSQL_HOST' MYSQL_USER='$MYSQL_USER' MYSQL_PASS='$MYSQL_PASS' BACKUP_DIR='$BACKUP_DIR' Additionals: $@"
OPTARG
内部から長さがゼロかどうかを確認できない理由はありますgetopts ... while ... case
か?
私自身の引数の検証を実行するためのより良い方法は何だgetopts
、私はに頼ることにしたくない場合には:)
。while ... case ... esac
?の外で引数の検証を実行します。
次に、引数の値が-d
etcになり、不足しているオプションをキャッチできなくなる可能性があります。
while
オプションに対して実行されているループが実際にあるという事実について考えたら、完全に理にかなっています。これは、他の方法と比較して冗長であるにもかかわらず、スクリプトで何が行われているのかが非常に明確であるため、私が行ってきた方法です。そして、この場合、他者による保守性が重要です。