対話メニュー作成(selcet コマンド)

select コマンドで選択肢を表示する

select コマンドは in の後に指定した単語のリストを番号付きで標準エラーに出力します。そのあとにプロンプト「#?」を出力して標準入力から入力されるまで待機します。

code
select n in a b c; do
  echo "${n}"
done
stdout
stderr
1) a
2) b
3) c
#? 

単語のリストに対応する番号とエンターを入力すると、対応する単語が select に指定したに格納されます。また読み込んだ行は REPLY 変数に格納されます。

code
select n in a b c; do
  echo "n=${n}"
  echo "REPLY=${REPLY}"
done
terminal
1) a
2) b
3) c
#? 1⏎
n=a
REPLY=1
#? 

先ほどのサンプルでは break で中断していますが、break で中断しない場合は EOF (CTRL-D) を入力するまで入力を求めるプロンプトが繰り返し表示されます。

code
select n in a b c; do
  echo "n=${n}"
done
terminal
1) a
2) b
3) c
#? 1⏎
n=a
#? 2⏎
n=b
#? 3⏎
n=c
#? CTRL-D⏎
code
select n in a b c; do
  echo "n=${n}"
done << 'EOF'
1
2
EOF
terminal
1) a
2) b
3) c
#? n=a
#? n=b
#? 

単語のリストにない番号を入力した場合は select に指定した変数にはブランクが設定されます。何も入力せずにエンターを入力した場合は単語のリストを番号付きで標準エラーに再度出力します。

code
select n in a b c; do
  echo "n=${n}"
done
terminal
1) a
2) b
3) c
#? 4⏎
n=
#? ⏎
1) a
2) b
3) c
#? CTRL-D⏎

select コマンドのプロンプトを変更する

select コマンドの入力を求めるプロンプトは PS3 変数が使用されます。プロンプトを変更するには、この PS3 変数に表示したい文字列を設定します。

code
echo "PS3=${PS3}"
PS3="選択する番号を入力してください: "
select n in a b c; do
  echo "n=${n}"
done
terminal
PS3=
1) a
2) b
3) c
選択する番号を入力してください: 1⏎
n=a
選択する番号を入力してください: CTRL-D⏎

select コマンドを使用したサンプル

code
touch {a..c}.txt

PS3="削除するファイルの番号:"
echo "------------------------------"
echo "削除するファイルを指定してください"
select f in *; do
  if [[ ${REPLY} == 'c' ]]; then
    echo ">>> 終了します"
    break
  elif [[ -n "${f}" ]]; then
    if rm "${f}"; then
      echo ">>> ${f}を削除しました"
    else
      echo ">>> ${f}を削除できませんでした" 1>&2
    fi
  else
    echo ">>> 番号を指定してください" 1>&2
  fi
done
echo "------------------------------"
ls
terminal
------------------------------
削除するファイルを指定してください
1) a.txt
2) b.txt
3) c.txt
削除するファイルの番号:1⏎
>>> a.txtを削除しました
削除するファイルの番号:3⏎
>>> c.txtを削除しました
削除するファイルの番号:3⏎
rm: cannot remove 'c.txt': No such file or directory
>>> c.txtを削除できませんでした
削除するファイルの番号:d⏎
>>> 番号を指定してください
削除するファイルの番号:c⏎