read
コマンドを使用するときに特定のオプションのみを有効にし、間違った可能性が入力された場合はスクリプトを終了しようとしています。
多くの可能性(配列、変数、構文の変更)を試しましたが、それでも最初の問題が解決しません。
ユーザーの入力をテストして、残りのスクリプトの実行を\禁止する方法を教えてください。
#!/bin/bash
red=$(tput setaf 1)
textreset=$(tput sgr0)
echo -n 'Please enter requested region > '
echo 'us-east-1, us-west-2, us-west-1, eu-central-1, ap-southeast-1, ap-northeast-1, ap-southeast-2, ap-northeast-2, ap-south-1, sa-east-1'
read text
if [ -n $text ] && [ "$text" != 'us-east-1' -o us-west-2 -o us-west-1 -o eu-central-1 -o ap-southeast-1 -o ap-northeast-1 -o ap-southeast-2 -o ap-northeast-2 -o ap-south-1 -o sa-east-1 ] ; then
echo 'Please enter the region name in its correct form, as describe above'
else
echo "you have chosen ${red} $text ${textreset} region."
AWS_REGION=$text
echo $AWS_REGION
fi
ケースを使用しないのはなぜですか?
case $text in
us-east-1|us-west-2|us-west-1|eu-central-1|ap-southeast-1|etc)
echo "Working"
;;
*)
echo "Invalid option: $text"
;;
esac
地域の名前を入力する必要がないようにして、ユーザーの生活を少し楽にしてみませんか?
#!/bin/bash
echo "Select region"
PS3="region (1-10): "
select region in "us-east-1" "us-west-2" "us-west-1" "eu-central-1" \
"ap-southeast-1" "ap-northeast-1" "ap-southeast-2" \
"ap-northeast-2" "ap-south-1" "sa-east-1"
do
if [[ -z $region ]]; then
echo "Invalid choice: '$REPLY'" >&2
else
break
fi
done
echo "You have chosen the '$region' region"
ユーザーがリストから有効な数値オプション以外を入力すると、$region
の値は空の文字列になり、エラーメッセージが表示されます。選択が有効な場合、ループは終了します。
それを実行する:
$ bash script.sh
Select region
1) us-east-1 4) eu-central-1 7) ap-southeast-2 10) sa-east-1
2) us-west-2 5) ap-southeast-1 8) ap-northeast-2
3) us-west-1 6) ap-northeast-1 9) ap-south-1
region (1-10): aoeu
Invalid choice: 'aoeu'
region (1-10): .
Invalid choice: '.'
region (1-10): -1
Invalid choice: '-1'
region (1-10): 0
Invalid choice: '0'
region (1-10): '
Invalid choice: '''
region (1-10): 5
You have chosen the 'ap-southeast-1' region
問題はこれにあります:
[ "$text" != 'us-east-1' -o us-west-2 -o ... ]
-o
はorを意味し、完全な条件が必要なので、
[ "$text" != 'us-east-1' -o "$text" != 'us-west-2' -o ... ]
毎回$text
をテストする方法をご覧ください。
あなたのlogicも間違っています。 -a
(および); 「us-east-1」でない場合and「us-west-2」でない場合andない...
そう
[ "$text" != 'us-east-1' -a "$text" != 'us-west-2' -a ... ]
この種のテストを行う方法は他にもあります。一部は単に「個人的な好み」です。ただし、この構文を使用すると、元の形式と構造に従うことができます。
コマンドラインオプションを使用できるようにする(以前のコマンドラインを編集して再利用する方が簡単で、スクリプトで使いやすい)のではなく、質問をするスクリプトには本当に耐えられないので、次のようにgetopts
を使用します。
_#!/bin/bash
regions=(us-east-1 us-west-2 us-west-1 eu-central-1 ap-southeast-1
ap-northeast-1 ap-southeast-2 ap-northeast-2 ap-south-1
sa-east-1)
region=0 # default to region 0, us-east-1
usage() {
[ -n "$1" ] && printf '%s\n\n' "$@"
echo "Usage: $0 [ -r region-number|\"list\"] ..."
# print more help here
exit 1
}
list_regions() {
[ -n "$1" ] && printf '%s\n\n' "$@"
printf '%s\n' "${regions[@]}" | cat -n
exit 1
}
check_region() {
[ "$region" == "list" ] && list_regions
[[ ! "$region" =~ ^[0-9]+$ ]] && usage "Region code must be numeric"
region=$((region - 1)) # bash arrays are zero-based
[ -z "${regions[$region]}" ] || \
[ "$region" -lt 0 ] && list_regions "Unknown region code"
}
while getopts 'r:h' opt ; do
case "$opt" in
r) region="$OPTARG" ; check_region ;;
h) usage ;;
*) usage ;;
esac
done
shift $(($OPTIND - 1))
# do whatever with "$region" and/or "${regions[$region]}"
echo region="${regions[$region]}"
_
いくつかの例を実行します:
_$ ./busted.sh
region=us-east-1
$ ./busted.sh -r
./busted.sh: option requires an argument -- r
Usage: ./busted.sh [-r region-number|"list"] ...
$ ./busted.sh -r list
1 us-east-1
2 us-west-2
3 us-west-1
4 eu-central-1
5 ap-southeast-1
6 ap-northeast-1
7 ap-southeast-2
8 ap-northeast-2
9 ap-south-1
10 sa-east-1
$ ./busted.sh -r 99
Unknown region code
1 us-east-1
2 us-west-2
3 us-west-1
4 eu-central-1
5 ap-southeast-1
6 ap-northeast-1
7 ap-southeast-2
8 ap-northeast-2
9 ap-south-1
10 sa-east-1
$ ./busted.sh -r 7
region=ap-southeast-2
_
あなたはこのようなことをすることができます:
valid=(foo bar doo)
echo enter something, valid values: "${valid[@]}"
read text
ok=0
for x in "${valid[@]}" ; do
if [ "$text" = "$x" ] ; then ok=1 ; fi ;
done
echo is it ok: $ok
有効な値はbash配列に保存されます。これは、表示と入力文字列のテストの両方に使用できます。
-o
in test
には完全な条件が必要です。使用してはいけない引数もあります
[ "$x" != "foo" -a "$x" != "bar" ]
代わりに
[ "$x" != "foo" ] && [ "$x" != "bar" ]