2つのスイッチ-hと-dを使用してスクリプトを作成しようとしています。 -d には必須の数値引数があります。その後、未決定数のファイルパスがあります。これまでこれを持っていますが、コードが間違ったスイッチ-r(どんな名前でも可能)を認識していないようで、スイッチを入力しないと機能しません。
while getopts ":hd:" opt; do
case $opt in
h)
echo $usage
exit 0
;;
d)
shift 2
if [ "$OPTARG" -eq "$OPTARG" ] ; then # ako dalsi argument mame cislo
depth=$OPTARG
fi
;;
\?)
shift 1
;;
:)
shift 1
;;
esac
done
echo $1
と入力すると、./pripravne1.sh -d /home/OS/test_pz/test2
以下が表示されます./pripravne1.sh: [: /home/OS/test_pz/test2: integer expression expected
。入力すると空の./pripravne1.sh -r /home/OS/test_pz/test2
文字列のみが表示されます。
ベストアンサー1
[ "$OPTARG" -eq "$OPTARG" ] ...
$OPTARG
数値であることを確認する正しい方法ではありません。数値でない場合、ユーザーに迷惑な理解できないエラーが印刷または返されることがあります。本物すべての場合(in ksh
)でtrueを返すか、null $OPTARG
(in)に対してもzsh
trueを返します。
また、引数を受け入れるオプションを or-d12
形式で与えることができる-d 12
ため、ブラインドインジェクションがshift 2
切り捨てられない。shift
ループ内で実行すると、ループgetopts
自体がリアルタイムパラメータリストを使用するため、深刻な対話が発生する可能性があります。
これを念頭に置いて、私のアドバイスは次のとおりです。
die(){ echo >&2 "$@"; exit 1; }
usage(){ echo >&2 "usage: $0 [-h] [-d num] files..."; exit 0; }
depth=0
while getopts :hd: opt; do
case $opt in
h) usage ;;
d) case $OPTARG in
''|*[!-0-9]*|-|*?-*) die "invalid number $OPTARG" ;;
*) depth=$OPTARG ;;
esac
;;
:) die "argument needed to -$OPTARG" ;;
*) die "invalid switch -$OPTARG" ;;
esac
done
shift "$((OPTIND - 1))"
echo depth="$depth"
echo files="$@"