0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

shとbashでselect構文を使ってみる

Last updated at Posted at 2019-05-17

shやbashにはselectという便利な構文がある。select構文を使うとin以降に与えた複数の引数をメニューっぽく表示して選択させてくれる。数字を選択すると、対応する引数の値が指定された変数に代入されdo以下が実行される。範囲外の数字を入力すると再度入力を促される。Enterだけ入力すると再度メニューが表示される。Ctrl-Dを押下するとselect文は終了する。

/bin/shの場合

➤ env -i /bin/sh
sh-4.1$
sh-4.1$ select x in aa bb cc; do echo $x; done
1) aa
2) bb
3) cc
# ? 3
cc

inの後に複数の引数ではなくセミコロン、コロン、スペースなどで区切った文字列を渡しても気を利かせてくれるわけではない。

sh-4.1$ select x in "aa;bb"; do echo $x; done
1) aa;bb
# ?
sh-4.1$ select x in "aa:bb"; do echo $x; done
1) aa:bb
# ?
sh-4.1$ select x in "aa bb"; do echo $x; done
1) aa bb
# ?

/bin/bashの場合

shでは変数に型という概念は無く、すべての変数はただの文字列である。
これに対してbashの変数は値として配列もとることができる。
そこでselect構文においてinの後に配列を持つ変数を展開すべく
$mを書いてみたが、単に${m[0]}の代わりにしかならなかった。

$ env -i /bin/bash
bash-4.1$ m[0]=item1
bash-4.1$ m[1]=item2
bash-4.1$ m[2]=item3
$ declare -p m
declare -a m='([0]="item1" [1]="item2" [2]="item3")'
bash-4.1$ select x in $m; do echo $x; done
1) item1
# ? 1
item1

おまけ)bashにおける配列型変数

bashでは変数が配列を持っている場合 [0][1]というインデックス
を省略すると、それは単に[0]を指すだけである。

$ declare -p m
declare -a m='([0]="item1" [1]="item2" [2]="item3")'
$ echo $m
item1
$ echo ${m}
item1
$ echo ${m[0]}
item1
$ declare -p m
$ m=hogehoge
$ declare -p m
declare -a m='([0]="hogehoge" [1]="item2" [2]="item3")'
$ echo $m
hogehoge

おまけの続き)

コメントでbashで配列を持っている変数の添え字(?)に@を使うとすべての要素が取り出せるよと @akinomyoga さんに教えていただきました。

$ x[0]=aa
$ x[1]=bb
$ echo ${x[@]}
aa bb
$ select y in "${x[@]}"; do echo $y; done
1) aa
2) bb
# ? 1
aa
0
2
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?