変数に私が望むものだけが含まれており、他のものが含まれていないことを確認してください。

変数に私が望むものだけが含まれており、他のものが含まれていないことを確認してください。

ソースからソフトウェアをビルドするスクリプトを作成しており、--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 wantawkどうすればいいのかわかりません。

ベストアンサー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でこれを行うこともできます。

おすすめ記事