1. Qiita
  2. 投稿
  3. ShellScript

任意のシェルコマンドを対話モード化するshellscriptを書いた

  • 4
    いいね
  • 0
    コメント

今北

これ作った
gif

概要

任意のコマンドを対話モード化するためのコマンドinteractをつくった

例えば、このタブではgitしか弄らないんだから、毎回『git』って打つのめんどうなだけだし省略したい、などの問題を解決する

目的

メインの目的は単に自分がシェルスクリプトの練習したいと思ったからで、中身は初心者のだいぶひどいコードだと思う

需要はないだろうけどちょっと自分用に欲しかった。
類似のものが既出なら普通にそっちを使いたいからあったら教えて欲しいorz

インストール

https://github.com/ahyahya/interact
にあるinteract/usr/local/binにぶちこんで、
$ chmod +x /usr/local/bin/interact する

実装

アローキーとかでヒストリー参照さえしないのなら

#!/bin/bash
read args
while test ...
do
  line=$cmd" "$args
  `echo $line`
  read args
done

で十分なんだけど、そんなことはないので一文字ずつ入力を受け付けてる

readlineにたよりまくるって手に逃げれなかったのがつらかったし、
そうなってる時点で制作コンセプトが間違ってるんだと思う

あたらしい知見

アローキーの検出

アローキーの排出する文字列ってこれで取れるのね

アロー アローをreadしたときに取れる文字列
$'\x1b\x5b\x41'
$'\x1b\x5b\x42'
$'\x1b\x5b\x43'
$'\x1b\x5b\x44'

read key; echo "$key" | hexdumpってしてからキーを入力すると、
そのキーの16進がとれるからそれを利用すればどんなキーでも取れる(と思う)

バックスペースの検出

これに関しては上の例外。

今回は1文字ずつ入力を見てるので、実はバックスペースにあたる零幅文字と比較すればいい。

具体的には以下をしてる:

while IFS= read -r -n1 -s char; do 
  if [ "$char" = "" ] ; then # backspace (compare to zero with non joiner)
    # ...
  fi
  # ...
done

同じ行の標準出力を上書きしたり消したりしたい

printf '\r%s' "てきとう"

を使う。これは、「今の行の先頭にカーソルを移動して、上から "てきとう" と出力する」という意味