rcmdnk's blog

20140124_sentaku

最近作り直してた multi_clipboardsd_cltrashで使っていた シェルスクリプトでの対話的な選択画面を他でも簡単に使える様にしてみました。

sentaku

名前に困ったので日本語で。

Bash (3.X以降)とZsh (4.X以降)で動くことは確認してあります。 (何かおかしかったら教えてください。)

単体で使う

スクリプト単体だとそのまま実行しても何もしませんが、 lsなんかの出力をパイプで渡してあげる下のgifみたいな感じで選んで、 選んだものを出力できます 1

sentaku

最後に返される値だけが標準出力で、 他の選択画面は直接端末(/dev/tty)に送られるので、 上にある例のように$()内で使ってあげれば選んだものを 変数に入れたり、

$ less $(ls | sentaku)

みたいにすればディレクトリにあるファイルの一覧を表示して、 見て選んでから直接lessで開けます。 (vimvim .としてカレントディレクトリを開くみたいな感じ。)

長い同じような名前のファイルが沢山ある場合に、 lsで表示させてからマウスでコピーして。。。みたいなことを しなくて済みます2

シェルスクリプトを使っていて複数から1つ選ぶ様なことをするときに、 一覧を表示させて番号を入力させる、といった様なものを ちょっとだけグレードアップしてくれます。

ライブラリみたいに使う

細かく関数に分けて実装してみたので、 sentaku自体をsoruceして、適当に関数を置き換えてあげるだけで 新しいものが作れます。

オリジナルのものは一覧を表示させて選んだものを最後い返すだけですが、 選択画面で押すキーについて、全て

  • a~z: _sf_a ()~_sf_z()
  • A~Z: _sf_A ()~_sf_Z()
  • 0~9: _sf_0 ()~_sf_9()

と割り振られてるので、その関数に適当に動作を与えればそのキーを押した時に 実行されます。 詳しくはGitHubのReadmeと一緒に入ってるexampleで。

Examples

スニペットツールみたいに使う

BashとZshそれぞれでちゃんと動くよ、というテストを兼ねた簡単な実装。

最初に、

source sentaku -n

と、sentakuを読み込みます。この時に、メイン関数が呼ばれないように-nを付けて 読み込みます。 (スクリプト自体をパイプ後に実行すると、そのままだと この読み込み部分でもsentakuの メイン関数が呼ばれてしまうので)

直接実行すると、パイプ入力の代わりに~/.my_inputというファイルから インプットを受け取って選べます。 なので、スニペットツール的な感覚で使えます。 (multi_clipboard)にある機能と同じ感じ)

何か追加したい時は

$ ./ex_source_bash.sh -p aaa bbb ccc

の様に-pに続いて入力してください。 これらのスクリプトでは区切りを$'\x07'(BEL)にしてあるので、 BEL信号を含む様な余程特殊な文字列出ない限り スペースがあろうが改行があろうが1つの塊になります。 ファイルの中身を全部登録したい時は

$ cat file | ./ex_source_bash -p

としてもOK。パイプ入力がある場合は-pを付けた場合、 パイプからの入力を登録します。

ファイルエクスプローラー

エクスプローラー的なことをするスクリプト。

起動すると現在のディレクトリのファイルとディレクトリ一覧が表示されて、 ディレクトリを選ぶとそのディレクトリに移動します。

後はsで詳細、dで削除、llessで中身表示、eで編集 3 的なことが出来ます。

スクリプトにあるように、lには

1
2
3
4
5
_sf_l () {
  clear >/dev/tty
  less ${_s_inputs[$_s_current_n]} >/dev/tty </dev/tty
  _sf_quit
}

という風に、lessでファイルを開いて、その後終了するだけの内容が書かれてますが、 ${_s_inputs[$_s_current_n]}というのが現在カーソルがある位置の ものに当たるので4 これを開いてるだけです。

なので、適当なキーに、この値を適当なコマンドに与える様な関数を割り当てれば 選んだファイルを操作する様な事が出来ます。

一度選んで作業後、引き続き他を選びたい、といった場合には、上で _sf_quitを除けば再び選択画面に戻ります。

メニュープログラム

コマンドが予め決まってて、選んだコマンドを実行するスクリプト。

  • Keybaord Input
  • ls
  • pwd
  • date
  • more

という項目から選べて、キーインプットを直接返したり、 lsの結果を返したりするだけですが、 最後のmoreの所では スクリプト内の関数の中で、さらにsentakuを読み込んで別の 選択画面を作る様になっています。

moreを選ぶと

  • echo aaa
  • echo bbb
  • echo ccc
  • echo ddd

という新しい画面に行ってこれらを選んでもそれが実行されます。 また、qを押すと戻れます。

スクリプト内で二重にsentakuを呼ぶ時は、重複して呼びたくない部分があるので、 sentaku -n -cと言った風にcを付けて読み込みます。

ゲーム

単にいきなり敵が現れて簡単なコマンドを使えるだけのゲーム。

  • ./ex_slime.sh # Japanese
  • ./ex_slime.sh -e # English

で、日本後バージョンと英語バージョン。

基本的に逃げられませんが、逃げ続けると。。。

まとめ

色々使い道はありそうだと勝手に思ってますが、 何か面白いものができたら教えて頂けたりすると嬉しかったりします。

Sponsored Links
  1. lsの出力はスペースを含む場合がるのでしっかり使いたい場合は 区切り文字を改行にするためsentaku -s $'\n'とします。 デフォルトの区切りは$IFSです。

  2. GNU screenやtmuxを使ってると画面自体からキーショットカットでコピペが出来るので 必要ないわけですが。。。

  3. $EDITOR、もしくは設定されてない場合はvim)

  4. _s_inputsはインプットから作られるリストで、_s_current_n が現在のカーソル位置の番号

Sponsored Links

« シェルスクリプトで`read -s`を使う時の問題 sentakuに検索機能追加 »

}