【コラム】

漢のzsh

3 同じことを2度するなんて…… 自分の過去は利用しましょう

3/24

漢は2度入力しない - コマンド履歴

一度入力したコマンドをもう一度馬鹿正直に入力するという愚直な行為はぜひとも避けたい。lsとか短いコマンドは入力した方が早いだろうが、長いコマンドを入力し直すのはカッコ悪い。高機能シェルには「コマンド履歴」という「覚えておく機能」がある。zshのそれは特に強力だ。これは使わざるをえないだろう。

ということで早速リスト1.1を追加だ。

HISTSIZEとSAVEHISTで保存するコマンドの数を指定する。10,000はやり過ぎだとおもうかもしれない。しかし、実際はこの程度ではむしろ手ぬるい。漢はもはや一度入力したコマンドは未来永劫直接入力はしないものだ。回りを見渡すと億単位を越えてありえないサイズを指定している人もいる。

1,000では少ない。100,000くらいでもいい。一週間使ってみて、保存したい年数に換算しなおして行数を算出するといいだろう。たとえば一週間で2,000履歴ほどたまったとすれば、向こう50年間分保存するとしてざっくり計算すれば2,000×4.5×12×50=5,400,000だから、まぁ6000000あたりを指定しておけばいい。

リスト1.1 コマンド履歴機能

HISTFILE=~/.zsh_history
HISTSIZE=10000
SAVEHIST=10000
setopt hist_ignore_dups     # ignore duplication command history list
setopt share_history        # share command history data

こんな感じだ。コマンド履歴機能を有効にしてから図1.2のようにコマンドを入力する。次に、↑キーを押すと図1.3のようにひとつまえのコマンドが表示される。さらに↑キーを押すと図1.4のようにさらにひとつ前のコマンドが表示される。↑キーと↓キーで入力したコマンドを表示できるという寸法だ。

図1.2 コマンド履歴機能を有効にしてからコマンドを入力する

図1.3 ↑キーを押すとひとつ前のコマンドが表示される

図1.4 ↑キーをさらに押すとさらにひとつ前のコマンドが表示される

ちなみにhistoryコマンドで図1.5のように履歴一覧を表示できる。数を指定しなければ直近のリストが、数を指定すればその数の分だけ遡って、0を指定すれば全部表示される。

図1.5 historyコマンドでコマンド履歴一覧を表示させることができる

bashやtcshユーザであれば、そんなものはbashやtcshでとっくに実現している、と思うかもしれない。はい、その通りです。しかしzshが違うのはここから(ちなみに、tcshでは履歴の共有は難しいが、できないこともない。それは後ほど)。

まず図1.6を見てみよう。これはインタラクティブシェルで制御構文を使って処理を実行したところだ。ちなみに処理内容はFreeBSDでほかの依存からではなくユーザによって直接インストールされたアプリケーションの一覧を出力させるというものだ。

図1.6 for in、ifといった制御構文を使ってスクリプトを実行

↑キーを押すと図1.7のように複数行のままコマンドが表示される。bashでは1行コマンドに変換されたものが表示されるし、tcshでは最初の1行しか表示されない。しかもzshでは、表示された複数行のコマンドをエディタでも使うように編集できる。たとえば図1.8のような感じになる。

図1.7 ↑キーを押すと複数行のままコマンドが表示される

図1.8 表示された複数行のコマンドはエディタでも使っているかのように編集できる

これはらくちん。

bashやtcshで同じことをしようとしたら、普通はシェルスクリプトファイルを作ってからそいつを実行することになる。入力したコマンドを編集する術がない、または編集しずらいから、いっぺんファイルに書き出した方が扱いやすいからだ。

しかしzshでは気のおもむくままに書いて、編集が必要ならその場で編集すればいい。これは便利だ。zshを使いだしてからシェルスクリプトをファイルに書くことが少なくなった。

漢のツールとはこれくらいスマートにありたいものだ。

図1.9 当然そのまま実行できるという寸法だ

図1.10 ちなみにhistoryでは1行に組み直されたコマンドが表示される

もはや漢のスクリプトはコマンド履歴の中にあるものだ。

ちなみにsetopt hist_ignore_dupsは同じコマンドを重複して記録しないようにするオプション、setopt share_historyはコマンド履歴ファイルを共有する設定だ。

漢のデスクトップはターミナルウィンドウで埋めつくされている(screen使えという話はおいておく)。それぞれにzshが動作しているわけで、それぞれのzshで入力したコマンドは全部覚えて共有しておきたいにきまっている。

これを実現するオプションがsetopt share_historyだ。本当に全部保存されているのか気になるのであれば、tail -f ~/.zsh_historyのように履歴ファイルを監視するといい。コマンドを入力するごとに書き込まれるのがわかるだろう。

HISTFILE=~/.zsh_historyで履歴データを保存するファイルを指定しているので、工夫すればほかのユーザとすらコマンド履歴を共有するという変態的設定すら実現できる。変態的ではあるが、他人のコマンドからスキルを盗めるのでワクワクするのは間違いない。

しかし、履歴の数が多くなると、全部↑↓キーでコマンドを表示させるのは無理? はい、その通りです。

普通は履歴から検索するのだが、それは次回に説明だ。

おまけ - tcshで変態をつらぬけ

今回説明した設定内容を設定ファイルにまとめたものを掲載しておく。ついでにtcshで同じような設定をする場合の例も紹介しておく。zshが使えない環境での参考にしてみてほしい。bashrcはzshrcと似たような感じなので掲載しなくてもいいだろう。特にtcshの変態的設定はかくもよだれを誘うに違いない。

リスト2.1 今回の設定ファイルまとめ ~/.zshrc

## Command history configuration
#
HISTFILE=~/.zsh_history
HISTSIZE=10000
SAVEHIST=10000
setopt hist_ignore_dups     # ignore duplication command history list
setopt share_history        # share command history data

リスト2.2 tcshで同じような設定をした場合 ~/.tcshrc

## Command history configuration
#
set histfile=~/.history-"${tty:as|/|-|}"
set history=1000
set savehist=1000
set histdup=erase
 
# merge history files
#
if ( -d /usr/bin/ ) then
    touch ~/.tcshhistory$$ "${histfile}"
    chmod 600 ~/.tcshhistory$$ "${histfile}"
    cat ~/.history* | paste - - | sort | uniq -f 1 | \
        awk '{print $1 "\n" substr($0, 14, length($0) - 13)}' | \
        tail -${history} \
        > ~/.tcshhistory$$
    mv ~/.tcshhistory$$ "${histfile}"
endif

tcshではまずヒストリファイルの共有ができない。ので、まずはset histfile=~/.history-"${tty:as|/|-|}"のようにして起動されたシェルごとに履歴ファイルを設定しておく。そして# merge history filesに書いてある魔法チックな処理だ。ここでコマンドを組み合わせてほかのtcshヒストリファイルを自力でマージしてやる。こうすることで起動時にほかのターミナルで保存された履歴データを共有できるといった寸法だ。

正直なところこの方法ではzshのように柔軟な共有はできないのだが、共有できないよりはましだろう(FreeBSDで動作することを確認している)。ただ、起動時に処理が実行されるので端末の起動が遅く感じられる。しかしまぁそこはそれ、一度起動したターミナルは二度と閉じなければ問題なしだ。

あ、それだと共有されるタイミングが…… ま、細かいことは気にしない。

3/24

インデックス

連載目次
第24回 グッバイ野郎ども! コピペではじめるzshファイナル
第23回 コマンド補完設定 - アーキテクチャタイプ編
第22回 もってけ泥棒! コピペで始めるzsh - リターンズ
第21回 コマンド補完設定 - ファイルシステムタイプ編
第20回 コマンド補完設定 - cal/ncalコマンド編
第19回 コマンド補完設定 - trafshowコマンド編
第18回 コマンド補完設定 - daemonコマンド編(2)
第17回 コマンド補完設定 - daemonコマンド編(1)
第16回 拡張子ごとにコマンドを自動実行 - 「alias -s」
第15回 **で簡単ヒット!!! - 漢達への熱いお願い付き
第14回 zshとscreenで最強のターミナル環境
第13回 タブキーは最強だ - ファイルグロブもサクっと展開
第12回 一時ファイルはもういらない - プロセス置換
第11回 zshはエディタか? - 「zed」でお手軽編集
第10回 もってけ泥棒! コピペで始めるzsh
第9回 世界はモノクロからカラーへ
第8回 これは既にシェルを超えている…… zshの算術演算
第7回 ひと味違うzshのリダイレクト
第6回 漢はだまって先方予測 - あなたはこの機能使いこなせるか
第5回 「あーっ!」というそのときのために - 備えあれば憂いなしの設定集
第4回 コマンド履歴の検索~EmacsとVi、どっちも設定できるぜzsh
第3回 同じことを2度するなんて…… 自分の過去は利用しましょう
第2回 取りあえず、プロンプトを整えておく。カッコつけたいからね
第1回 最強のシェル、それは「zsh」

もっと見る



人気記事

一覧

イチオシ記事

新着記事