zaki work log

作業ログやら生活ログやらなんやら

[Linux] ターミナルでコマンド履歴の検索とsttyのstop設定

bashzshはシェル上でCtrl-r押下してからコマンド名やオプションの文字列を入力すると、コマンド履歴からインクリメンタルサーチできる。

(reverse-i-search)`':

Ctrl-rを押下すると↑のようにプロンプトが変化するので、例えばここにkubectlと入力すれば、直近で実行したkbuectlコマンドを検索できる。(2つ目以前の候補検索は都度Ctrl-rを押下)

ただ、行き過ぎた場合はCtrl-sで戻れる設定になっているが、デフォルトではCtrl-sは端末のstopに割り当てられているため、コマンド検索でなくターミナルの入出力がロックされる。(解除はCtrl-q)
Ctrl-sは例えばリアルタイムで大量に流れ続けるログをtail -fで見ているときに一時停止したい場合などに使用する
※※ うっかりどこか変なキーコンビネーションを押してターミナルがまったく動かなくなった場合は(ネットワークが中途半端に切断された場合を除いて)これが原因のことが大半なのでとりあえずCtrl-qすれば動くかも

stty 設定

確認

この「Ctrl-sは端末のstop」という設定は stty -aで確認できる。

$ stty -a
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt -echoctl -echoke

使用頻度の高いCtrl-cCtrl-zなどもここで確認できる。

設定変更

設定を変更する場合、例えばstopCtrl-xにバインドするには以下を実行。
(^xは、Ctrl-vの後に制御コード入力でなく、ハット・スモールエックスの2文字でOK)

$ stty stop ^x

この後に確認すると、以下の通り、設定が変更される。

$ stty -a

... start = ^Q; stop = ^X; ...

設定無効化

「いや、stopなんか不要だ!一瞬でも目に入ればわかる!」って場合は、オフにもできる。

$ stty stop undef

この設定を行うと、内容は以下の通り。

$ stty -a
speed 38400 baud; rows 30; columns 246; line = 0;
... start = ^Q; stop = <undef>; ...

:

詳しくはman stty参照。

永続的に設定したい場合は、$HOME/.bashrcにこれらのコマンドを書いておけばOK

まとめ

コマンド履歴を新->旧方向へインクリメンタルサーチするにはCtrl-rをタイプする。
プロンプトは以下。

(reverse-i-search)`':

コマンド履歴を旧->新方向へインクリメンタルサーチするにはCtrl-sをタイプする。
ただしデフォルトで端末制御がCtrl-sを喰ってしまうので使いたい場合はそちらは無効化するか別キーを割り当てる。
プロンプトは以下。

(i-search)`':

いずれもEmacsキーバインドと同じで、Ctrl-risearch-backwardCtrl-sisearch-forwardと、逆サーチ、順サーチがそれぞれ割り当てられている。

履歴のインクリメンタルサーチとCtrl-sによるstop / [unix][shell] | 戯術者の日記

ちなみにfzfを使えば、Ctrl-rで検索モードになったあと↑や↓で検索結果を選べるのでCtrl-s無くてもよかったりするけどね。