それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

bashのcd/pwd/pushd/popdのまとめ

cd コマンドを見直す

cd : change directory のコマンドを少し見直してみたいと思います。

cd コマンドの基本的な使い方

cd コマンドでは非常によく使う書式があって、それは以下のとおりだと思います。

コマンド 意味
cd 何も入力しない cd ~ と同じ cd $HOME される
cd ~ cd $HOME と同じ、~が$HOMEと同じ
cd - 一つ前のディレクトリにもどる
cd .. 一つ上のディレクト
cd /var 指定したディレクトリに移動する

cd - 便利すぎてやばい

cd - と打つと、一つ前のディレクトリに移動します。一つ前のディレクトリがないときは何も起きません。

cd - は何を見ているのか

cd -cd $ODLPWD *1と同じ意味になります。$OLDPWD は一つ前のディレクトリを記憶している環境変数です。

cd - による作業ディレクトリとの移動

cd - さえ知っておけば、楽になることもあります。

cd app/views
cd ../../config
cd - #  app/views
cd - # config

2つのディレクトリを相互に行き来するなら cd - だけで十分です。

pushd / popd / dirs

pushd / popd は ディレクトリを dirs スタックに積んでおいて、 push dirs / pop dirs することで、ディレクトリ行き来することが出来ます。3つ以上のディレクトリを行き来するなら、こちらも便利です。ただ、積み過ぎて混乱することも多いのですが。

pushd / popd / dirs はそれぞれ、次のような動作をします。

  • pushd で、cd したあとにdirs に詰む
  • popd で、dirs から取り出して cd する。
  • dirs で、スタックを確認
    例 /etc/apache2, /var/www, /var/log/apache2 を相互に行き来するとき
takuya@:www$ pushd /etc/apache2
/etc/apache2 /var/www
takuya@:apache2$ pushd /var/log/apache2/
/var/log/apache2 /etc/apache2 /var/www
takuya@:apache2$ popd
/etc/apache2 /var/www
takuya@:apache2$ pwd
/etc/apache2

またpushd / popd には、cd で一つ前2つ前、3つ前に戻ることも出来ます。

dirs 間を移動するだけの例
cd -$1
cd -$2
cd -$3

popd してしまうと消えてしまうので、 cdだけしたいときは上記のようにします。

使い勝手がいいとはいえない popd/pushd

pushd / popd は積んでいくには便利ですが、毎回ペアを使わなくてはいけないです。 cd - と組み合わせしまうと、ちょっと面倒になります。

なので、pushd を使うときは popdをやめて cd -$1 cd -$2 cd -$3 したほうが便利だと思います。

cd -のように履歴を使うほうが楽だと思います。

コマンド履歴のように移動履歴として使うには、少し不便かもしれません

個人的には、 cd -- cd --- みたいなのがアレば最高なんですが。

dirs からの削除

popd -n を使えば、移動せずに「スタックから削除」することが出来ます。

指定したスタックを削除することも出来ます。
popd +2
popd +3

ただ、やはりpushd / popd はシェルスクリプトで省力化するためだともいます。個人的には、interactive shell で多用するものではないような気がします。

そこで自動pushdも考えられるのだけれど。。。

zsh のシェルのオプションには、自動でpushd してくれる便利な機能があります。

bashではaliasするだけで実現できます。

alias cd=pushd

流石にコレは、パニックになりそう。

環境変数CDPATH

CDPATH は、cd コマンドの移動先を検索するパスになります。

CDPAH に登録しておくと、ディレクトリ名をCDPATHから探してくれます。

CDPATHの例
takuya@:www$ CDPATH=.:/var
takuya@:www$ cd log
/var/log

ただしcd 履歴やpushdの代わりに使うのは結構難しいとおもいます。事前設定やシェルスクリプトによる自動展開をつくることになり、そこまで便利な機能でもないかと思います。

ある程度省力化は出来ます。しかし同名のフォルダでかぶってしまうと、指定がめんどくさかったり、CDPATHを毎回確認しなくちゃいけなかったりするので、大量に使うのは不可能です。

本当に毎日のように使う定型業務とくに、仕事でログだけ見る仕事など運用担当者には重宝すると思いますが。

そこで、毎回入力を楽にする。

シェルのオプションには、次のようなオプションが用意されていて、自動的には設定されませんが、自分の任意で使うことが出来ます。

autocd         
cdable_vars    
cdspell        
autocd

autocd は、ディレクトリ名だけが入力されたとき、ディレクトリ名をコマンドのように「実行」します。cd /var/wwwの代わりに/var/www だけで移動できるようになります。ただしREPLとして実行しているときだけです。シェルスクリプトでは使えません。

cdable_vars

cd の引数でパスが見つからなかったら変数としてみなす。 つまり

app_view=app/view
app_ctrl=app/controller
cd app_view
cd app_ctrl

と出来ます。ダラー$が が省略できます。

cdspell

cdspell はスペルミスを見つけて、それっぽいディレクトリに移動してくれます。

takuya@:~$ cd /varr/wwww
/var/www
takuya@:www$ cd /varr/wwww
/var/www
takuya@:~$ cd /vaaaar/wwwwww
-bash: cd: /vaaaar/wwwwww: そのようなファイルやディレクトリはありません

あまり激しく間違うと見つけてくれませんが、数文字程度のtypo なら見つけてcd してくれます。

shopt で設定をOn/Off

shopt で設定をONにするときは

shopt -s cdspell    # set すると覚える

shopt で設定をOFFにするときは

shopt -u cdspell    # unset すると覚える

shopt で設定を確認するときは

shopt cdspell # 何もつけない

この辺はshoptの記事 でもう少し詳しく触れたいと思います。

glob との組み合わせ

一番便利なのはコレじゃないでしょうか。glob つまり * でめんどくさい入力を省略できます。

takuya@:www$ cd /v*/w*
takuya@:www$ pwd
/var/www

まぁ{TAB} を押してもいいのですが、cd 移動がコマンド履歴に残せる便利かもしれません。*2 日本語キーボードなら * が小指で押しやすいので利用は便利だと思います。

cdspell だけじゃなく dirspell もつけたら楽かもしれません

参考資料

おまけ

検索中に見つけた autojump という、移動管理ツールが便利そうです

https://github.com/wting/autojump

*1: 正確には cd $OLDPWD; pwd; です。

*2: shopt