bashのプロンプトに前回実行コマンドの終了ステータスコードを表示する

zsh の walters 等のプロンプトテーマは「前回実行したコマンドの成否 (exit status / return code) に応じて表示を変える」ようになっている。これは非常に良いなと思ったため bash で同じコトができないか調べてみた。

結論としては、PS1 変数に以下のようなコマンドを埋め込むことで実現するのが良さそうだった:

  1. 終了ステータス ($?) の値を一次変数に記録
  2. その一次変数を使って表示を切り替える

条件判定のために if を使う(=test コマンドを実行する)ので、判定処理の後でその値を使いたければ終了ステータス値は退避しておく必要がある。またプロンプト表示のタイミングで評価してもらいたい環境変数の $ 記号はエスケープが必要になる。これら 2 点に注意。

試行錯誤の結果、本日時点で落ち着いた設定を次に書いておく。ユーザー名@ホスト名:カレントディレクトリ$ という形式のプロンプトで、ただし直前のコマンド失敗時は先頭に赤文字で終了コードを表示している。

# ~/.bash_profile 抜粋
rst='\[\e[0m\]'
ul='\[\e[4m\]'
red='\[\e[0;31m\]'
PS1="\$("
PS1+="status="\$?"; "
PS1+="if [ \$status -ne 0 ]; then echo \"$red[\$status] $rst\"; fi"
PS1+=")"
PS1+="\u@\h:${ul}\w${rst}\$ "
unset rst ul red

なお PROMPT_COMMANDPS1 を設定する方法もあり、よく紹介されているけれど、そちらは Anacondavirtualenv といった PS1 を書き換えるツールと相性が悪く、それらによる動的なプロンプト書き換え処理が無効化されてしまう問題があった。その点、上記の方式は問題ない。Python を使う人は、コマンド埋め込みの方が良いと思う。Anaconda 環境での表示例を、次に貼り付けておく。

f:id:sgryjp:20191103233026p:plain

参考

以下の Web ページを参考にさせていただいた。

stackoverflow.com wiki.archlinux.jp