コマンドが失敗したらプロンプトを赤くする (2)
しばらく前から、コマンドの終了ステータスをプロンプトの色に反映させるようにしている。
終了ステータスとは
C言語なら
int main(int argc, char* argv[]) { ... return 0; }
この return している 0 が終了ステータス。この整数値の下位 8bit がプロセスの終了時に親 (そのプロセスを起動したプロセス) にわたる。
終了ステータスの指定方法はいろいろある。C言語の場合 main 関数の戻り値以外にも exit 関数の引数でも指定できる。Ruby, Perl の場合、そもそも main 関数は無くて exit 関数に引数を与える方法だけがつかえる。
この値はシェル上で $? で参照できる。
% perl -e 'exit(0xdead)'; echo $? 173 %
慣例として、正常終了のときは 0 を返すことになっている。
% ls /etc/passwd /etc/passwd % echo $? 0 % ls /etc/passwdddd ls: /etc/passwdddd: No such file or directory % echo $? 1 %
ファイルが存在して無事表示できたので 0, ファイルが存在しなかったときは 1 を返しているのがわかる。ここではこの二種類しか観測できなかったけど、例えば grep だと 2 もあります。
% echo hello | grep hello hello % echo $? 0 % echo hello | grep helo % echo $? 1 % echo hello | grep Usage: grep [OPTION]... PATTERN [FILE]... Try `grep --help' for more information. % echo $? 2 %
パターンにマッチする行が見つかったら 0, 見つからなければ 1, そもそもそれ以前の問題 (引数が足りない) の場合 2 を返している。
プロンプトの色を変える
やっと本題。zsh だと ~/.zshrc にこんな感じで書くと良い。
autoload -U colors colors PROMPT="%{$fg[green]%}%#%{$reset_color%} " precmd () { PROMPT="%{%(?.$fg[green].$fg[red])%}%#%{$reset_color%} " }
%(?.foo.bar) ってところで条件分岐しているだけです。くわしくは zshmisc (1) の “Conditional substrings” を参照。なので、色以外も切り替えられます。
PROMPT="('-')/ " precmd () { PROMPT="(%(?.'-'.;_;))/ " }
うん。
('-')/ echo hello hello ('-')/ echoo hello zsh: command not found: echoo (;_;)/ echo hello hello ('-')/
かわいすぎた。
追記
はてなブックマーク - @lukesilvia.bookmarks
RPROMPT 使っている場合は、%{$reset_color%} のしないと、RPROMPT が手前にずれる
というコメントを読んで、PROMPT 中のエスケープシーケンスを %{ … %} でかこっていない部分に気づいたので「プロンプトの色を変える」の最初の例を修正しました。
% echo -n $fg[green] | hexdump -c 0000000 033 [ 3 2 m 0000005 % echo -n $fg[red] | hexdump -c 0000000 033 [ 3 1 m 0000005 % echo -n $reset_color | hexdump -c 0000000 033 [ 0 0 m 0000005 %
ここらへんは全部エスケープ (033) が含まれてます。
Dubhead
面白いアイディアと思います。
UbuntuのZsh 4.3.6で試したところ、Ctrl-C入力で赤プロンプトになっちゃいますが、
これ何とかなりませんかね…
kzys
私がつかっている Mac と Linux でもなります。
そういうものだと受け入れてましたが、なぜそうなるかは気になるので、時間ができたときに調べてみます。