直前のコマンドの終了ステータスでプロンプトを変更する。

またもbashのPS1ネタです。
前に.bashrcの設定でPS1に終了ステータスを使ってたけど使えなくなった!などと書いたのですが、原因がわかりました。
そんなわけで、(個人的には)なかなか便利な(と思う)PS1の設定。
具体的には直前のコマンドの終了ステータスが非0の時は、プロンプト末尾の"$"を赤くします。



まぁ、単純に

export PS1="...(ry)... \$(if [ $? -ne 0 ]; then echo -n "\[${COLOUR_RED}\]"; fi)\$\[${COLOUR_DEFAULT\] "

みたいに書けばokなんですが、ひとつ落とし穴がありまして...。
どうやらPS1の中で他にコマンドを実行しているとそいつの終了ステータスを拾ってしまうらしいのです。
うちの場合では"\$(cat ~/.atode | ... )"のようにatodeコマンドのスタックの深さをPS1に表示しているのでcatの終了ステータス(=0)が使われてしまって赤くならない...orz


と、いうことで、いろいろと小細工を加えたverがこちら

# ユーザ名を黄色で
PS_USER="\[${COLOUR_YELLOW}\]\u\[${COLOUR_DEFAULT}\]"

# ワーキングディレクトリ名(not path)を明るい白で
PS_WORK="\[${COLOUR_HIGHLIGHT_WHITE}\]\W\[${COLOUR_DEFAULT}\]"

# ホスト名を緑で
# Parttyセッション中ならホスト名をセッション名+"!"にする
if [ -n "${PARTTY_SESSION}" ] ; then
	PS_HOST="\[${COLOUR_GREEN}\]${PARTTY_SESSION}!\[${COLOUR_DEFAULT}\]"
else
	PS_HOST="\[${COLOUR_GREEN}\]\h\[${COLOUR_DEFAULT}\]"
fi

# screenを張っているときはWINDOW番号をシアンで
if [ -n "${WINDOW}" ] ; then
	PS_SCREEN="\[${COLOUR_CYAN}\]#${WINDOW}\[${COLOUR_DEFAULT}\]"
else
	PS_SCREEN=""
fi

# SSHで繋いでいるときは接続元IPをマゼンダで
if [ -n "${SSH_CLIENT}" ] ; then
	PS_SSH="\[${COLOUR_MAGENTA}\]/$(echo ${SSH_CLIENT} | sed 's/ [0-9]\+ [0-9]\+$//g')\[${COLOUR_DEFAULT}\]"
else
	PS_SSH=""
fi

# atodeやるべきことがあるときはその数を赤で
ATODE_FILE="${HOME}/.atode"
function ps_atode()
{
	a=$?;
	cat ${ATODE_FILE} 2>/dev/null | wc -l;
	exit $a;
}
if [ -f "${ATODE_FILE}" ]; then
	PS_ATODE="\[${COLOUR_RED}\]:\$(ps_atode)\[${COLOUR_DEFAULT}\]"
else
	PS_ATODE=""
fi

# ヒストリ番号を明るい青で
PS_HIST="\[${COLOUR_HIGHLIGHT_BLUE}\]\!\[${COLOUR_DEFAULT}\]"

# プロンプト記号を、終了ステータスが非0なら赤、0なら白で
function ps_exit()
{
	a=$?
	if [ $a -ne 0 ]; then
		echo -n "${COLOUR_RED}";
	else
		echo -n "${COLOUR_DEFAULT}";
	fi
	exit $a;
}
PS_EXIT="\[\$(ps_exit)\]\\$\[${COLOUR_DEFAULT}\]"

# それぞれ好みの順番で表示
export PS1="[${PS_USER}${PS_ATODE}@${PS_HOST}${PS_SCREEN}${PS_SSH} ${PS_HIST}:${PS_WORK}]${PS_EXIT} "

functionの部分がその小細工です。
まぁ、単にaという適当は変数に直前の終了ステータス保存して復元しているだけなんですが...。
サブシェルとかで出来ないかな?とか色々やってみたのですが...。
だれかよりよい方法があれば教えてプリーズ...。


ちなみに、SSHの接続元を表示する際にはfunction作ってませんが、これはPS1を生成するときに定数というかconstになるため。
function作ったり終了ステータスの保存が必要なのはPS1が動的に変わるようなときだけ。
という感じです。


bashはCtrl-cをプロンプトで押下したときに、$?を1にするようで、やたら赤くなるのですが...まぁ、いいでしょう。
makeとか時間掛かる+失敗しうるようなコマンドの後とかに結構便利に働いてくれます。
最初から"make && echo Succeed"とかすればいいのだろうけど、いちいちめんどうだし、終わった後で"echo $?"すればいいや、とか思っていたらTypoして$?が上書きされて...みたいなことが多々あったので作ってみましたとさ。


プロンプトを重くするのは如何なものか...という感じではありますが、まぁ、今のマシンだったらこれくらい大丈夫でしょう。うん。
そんなこんなのエントリでした。