tl;dr
ホントにちょっとした運用ツールを bash で作っていて, 複数の選択肢をリストアップしてメニューとして選択出来るようにしたいなーと思っていたら, bash には select 文という超絶便利な構文が用意されていたので使ってみました.
man bash
https://linuxjm.osdn.jp/html/GNU_bash/man1/bash.1.html より引用させて頂きつつ, 重要だなと思ったところをかいつまんで.
select name [ in word ] ; do list ; done in に続く単語のリストが展開され、要素のリストが生成されます。 展開された単語の集合が番号付きで標準エラー出力に出力されます。 「in word」が省略された場合、 位置パラメータが出力されます (後述の パラメータ を参照)。続いて PS3 プロンプトが表示され、標準入力から 1 行の読み込みが行われます。
list
が展開され, 各要素が番号付きで標準エラーに出力されるPS3
プロンプトが表示されて, 標準入力から番号の入力を待つ
PS3
を上書きすることで, オリジナルのプロンプトを出力出来るということですな.
読み込んだ行は変数 REPLY に格納されます。 break コマンドが実行されるまで、 選択を行うたびに list が実行されます。 select の終了ステータスは、 list 中で最後に実行したコマンドの終了ステータスですが、 コマンドが全く実行されなかった場合には 0 となります。
- 読み込んだ行は変数の
$REPLY
に格納される = 選択した文字が格納される (以下の実行例だと, )
以下, 実行例.
#!/usr/bin/env bash PS3="番号を選択して下さい. Enter 'q' for exit! > " menu="foo bar baz" item="" select item in $menu do if [ "${REPLY}" = "q" ]; then echo "終了します." exit 0 fi if [ -n "${item}" ]; then break else echo "invalid selection." fi done echo "${REPLY} を選択しました. 値は ${item} です."
以下, 実行例です.
いい感じです.
例
若干の
偏りがありますが, 最近, 少しずつ Kubernetes を触る機会が増えてきていて Kubernetes 触る上で複数のクラスタや Pod を切り替えたいというシチュエーションが出てきております.
Kubernetes クラスタを選択したい
複数のクラスタを管理していると, クラスタを切り替えることはあると思います. いちいち kubectl config get-clusters
で確認するのは飽きてきたので, 以下のようなスクリプトを作ってみました.
#!/usr/bin/env bash PS3="番号を選択して下さい. Enter 'q' for exit! > " menu="$(kubectl config get-clusters | sed '1d' | tr '\n' ' ')" item="" select item in $menu do # If enter 'q', exit this shell. if [ "${REPLY}" = "q" ]; then echo "終了します." exit 0 fi if [ -n "${item}" ]; then break else echo "invalid selection." fi done kubectl config use-context "${item}"
kubectl config get-clusters
の実行結果は以下の通りですが, この実行結果をリスト化しているのですが, kubectl get
のような --no-headers
が利用出来ないのが玉にキズです.
$ kubectl config get-clusters NAME gke_xxxxxxxxxx_asia-northeast1-a_oreno1-cluster-dev gke_xxxxxxxxxx_asia-northeast1-a_oreno2-cluster-dev docker-desktop
他に良いツールがあったら教えて下さい.
Kubernetes Pod を選択したい
Pod のログを確認しようとした時に, いちいち kubectl get pods
して Pod の NAME を確認することが辛かったので, 以下のようなスクリプトを作ってみました.
#!/usr/bin/env bash PS3="番号を選択して下さい. Enter 'q' for exit! > " menu="$(kubectl get pods --no-headers --output=custom-columns=NAME:.metadata.name | tr '\n' ' ')" item="" select item in $menu do # If enter 'q', exit this shell. if [ "${REPLY}" = "q" ]; then echo "終了します." exit 0 fi if [ -n "${item}" ]; then break else echo "invalid selection." fi done kubectl logs -f "${item}"
以下, 実行例です.
きっともっと良いツールが実は出回っているんだろうなあ... kubectl を直接叩くのは中学生までなんじゃ... という不安を抱えていますが, 今の所はこれで間に合っています.
以上
bash の select は令和の時代も役に立つ, その一例でした.