ソースからソフトウェアをビルドするスクリプトを作成しており、--platforms
オプションがあります。ユーザーが複数の項目を選択できるようにしたいのですが、間違いを防ぐ方法がわかりません。
例:
read -p "For what platforms do you wish to build [mac/win/linux32/linux64/all] ? "
if [[ -n "`echo $REPLY | grep 'win\|mac\|linux32\|linux64\|all`" ]] ; then
echo "ok"
else
echo "not ok"
fi
ユーザーが答えたらlinux32
大丈夫でしょう。
ユーザーが答えたらlinux32,mac
大丈夫でしょう。
ユーザーが答えたらうまくlulz
いかないはずです(そしてうまくいきません)。
ユーザーが答えると動作linux32,lulz
しません。 (はい、それは私の質問です。)
ユーザーが必要なものをカンマで区切って入力できるようにする方法を知っているかどうか疑問に思います。ただし、スクリプトが提供するオプションの1つである場合にのみ可能です。したがって、この場合はlinux32 linux64 mac win all
。
case
複数の入力を許可するか、1つを追加する方法がありますかelif $REPLY contains anything else than what we want
?awk
どうすればいいのかわかりません。
ベストアンサー1
read
入力を単語に分割し、結果を配列に保存できます。変数をIFS
単語区切り記号に設定します(文字列ではなく単一文字でなければなりません。値に複数の文字がIFS
含まれる場合、各文字は単語区切り文字です)。
IFS=, read -a platforms
次に、配列の各要素をサポートされているプラットフォームセットと比較して確認します。
for p in "${platforms[@]}"; do
case "$p" in
win|mac|linux32|linux64) :;;
all) platforms=(win mac linux32 linux64);;
*) printf 1>&2 "Unsupported platform: %s\n" "$p"; return 2;;
esac
done
複数のプラットフォームを一度に比較することもできます。これは、チェックコードでサポートされているプラットフォームセットをハードコードしたくない場合に便利です。
supported_platforms=(win mac linux32 linux64)
IFS=, read -a platforms
bad_platform_names=($(comm -23 <(printf '%s\n' all "${platforms[@]}" | sort -u) \
<(printf '%s\n' "${supported_platforms[@]}" | sort -u)))
if [[ ${#bad_platform_names[@]} -ne 0 ]]; then
printf "Unsupported platform: %s\n" "${bad_platform_names[@]}"
exit 1
fi
if printf '%s\n' "${platforms[@]}" | grep -qx all; then
platforms=("${supported_platforms[@]}")
fi
別のアプローチは、組み込み機能を使用して一度に1つのプラットフォームを要求することですselect
。
1もちろん、必要に応じて純粋なbashでこれを行うこともできます。