cdの引数を絶対パスにしてコマンドヒストリに残す
cdの引数が相対パスのままコマンドヒストリに残って便利な例が思いつかないので、絶対パスでコマンドヒストリに残すようにする。 具体的には、以下のシェル関数を.bashrcに書く。
if [[ -n "$PS1" ]]; then cd() { command cd "$@" local s=$? if [[ ($s -eq 0) && (${#FUNCNAME[*]} -eq 1) ]]; then history -s cd $(printf "%q" "$PWD") fi return $s } fi
いくつかの重要なポイントを以下に記す。
- cdの定義を上書きしているが、このような場合中で普通にcdを呼ぶと再帰してしまうため
command
組み込みコマンドを使う。 "$@"
の代わりに"$1"
を使うことはできない。cdを引数なしで呼んだときホームディレクトリに移動しなくなってしまう。- cdの成否は戻り値で判定できる。
history -s
は直前のヒストリを上書きするが、関数の中でcdが呼ばれたときは元の関数をヒストリに残したいので実行させない。- 配列変数
FUNCNAME
がコールスタックになっており、この配列の要素数が1かどうかでシェルから直接呼ばれているか(関数の中からでないか)判定できる。 - 文字列のquoteには
printf
組み込みコマンドを使う。%q
でquoteされた文字列が得られる。
Ctrl+Rによるヒストリ検索からディレクトリ移動できるようになって便利。
$ cd tmp/ $ cd space\ and\ meta\'\"\\characters/ $ cd .. $ cd $ history | tail (snip) 5033 cd /home/user/tmp 5034 cd /home/user/tmp/space\ and\ meta\'\"\\characters 5035 cd /home/user/tmp 5036 cd /home/user 5037 history | tail
追記(2014-12-11)
cdの戻り値を正しく返すように修正した。
追記(2014-12-11)
インタラクティブシェルとして起動したときのみ定義することをコードとして明記した。