コマンドラインで作業するときにおそらく一番目か二番目によく使うのが cd コマンド。たった 2 文字しかないので打つのも簡単です。しかし、深い高層のディレクトリ間を頻繁に移動するときに毎回ディレクトリを指定するのが面倒なことがあります。
カレントディレクトリが workspace1/html だったとします。ここから workspace2/html に移動したい場合は cd ../../workspace2/html
と入力します。そして今度は workspace1/js に移動したくなったら cd ../../workspace1/js
と入力します。workspace2/js に移動したくなったら cd ../../workspace2/js
と入力……ちょっと面倒ですよね。
このツリー構造はそこまで深くないので workspace1 内のディレクトリから workspace2 のディレクトリに移動しようと思ったら ../../workspace... だけでいいですが、フレームワークを使っていたりするともっと階層が深くなり、../../../../workspace... のようになり、.. を打つだけでも大変です。
ディレクトリスタックを使おう!
ディレクトリスタックとは、ディレクトリの位置をフルパスで複数保存しておくためのスタック(記憶領域)です。ディレクトリスタックにディレクトリのパスを保存するには pushd
、ディレクトリスタックの状態を確認するには dirs
、ディレクトリスタックのパスを削除するには popd
を使います。
実際に試してみましょう。先に紹介したツリー構造で、workspace1/html にいるとします。ここで、cd
コマンドの代わりに pushd
コマンドを使用して、workspace2/html に移動します。
$ pushd ../../workspace2/html
これで、workspace2/html に移動し、workspace1/html へのフルパスがスタックに積まれました。dirs
で確認してみましょう。
$ dirs
0 ~/workspace2/html
1 ~/workspace1/html
ここでもう一度、pushd
を実行すると、workspace2/html から workspace1/html に移動できます。さらに pushd
を実行すると workspce2/html にまた戻ってくることができます。
どういう仕組みなのか?
pushd
コマンドは、カレントディレクトリのフルパスをディレクトリスタックに積んで、指定した引数のディレクトリに移動するコマンドです。移動先のディレクトリを指定せずに単に pushd
だけで実行した場合は直前にいたディレクトリに移動できます。
$ pwd
~/workspace1/html
$ dirs
0 ~/workspace1/html # カレントディレクトリが 0 番目に積まれている
$ pushd ../../workspace2/html
$ dirs
0 ~/workspace2/html # 0 番目はカレントディレクトリ
1 ~/workspace1/html # 移動前直前のディレクトリが積まれる
$ pushd ../../workspace1/js
$ dirs
0 ~/workspace1/js # 0 番目はカレントディレクトリ
1 ~/workspace2/html # 移動前直前のディレクトリが積まれる
2 ~/workspace1/html # 古くなるごとに下に下がる
$ pushd # 移動先を指定しないと
0 ~/workspace2/html # 直前にいたディレクトリに移動する
1 ~/workspace1/js # pushd 直前のディレクトリが積まれる
2 ~/workspace1/html
pushd
で移動すると移動前のディレクトリをスタックに保存して移動するので、もう一度戻る際にはパスを指定せずに pushd
を実行すれば戻ることができます。dirs
でスタックを確認したときの 0 番目がカレントディレクトリ、1 番目に直前にいたディレクトリ、2 番目はさらにその前にいたディレクトリ、それ以降も同様に、古くなるごとに後ろに積まれていきます。
カレントディレクトリ(0 番目)から直前にいたディレクトリ(1 番目)に移動するには pushd
単体で良いのですが、2 つ前にいたディレクトリ(2 番目)に移動したい場合は pushd +2
とします。pushd +(番号)
と入力することで dirs
で確認した際の番号のディレクトリに飛ぶことができます。つまり、pushd
単体は pushd +1
と同じということですね!
要らなくなったパスは popd で削除!
ディレクトリスタックが以下の状態だったとします。
0 ~/workspace2/html
1 ~/workspace1/js
2 ~/workspace1/html
ここで、workspace2/html 内のコードはすべて書き終えたので、もうこのディレクトリに来ることはなくなったとします。このままだと workspace2/html のパスがスタックに積まれたままなので、移動するときの候補が多くなり、どこに移動すればいいのかがわかりにくくなってしまいます。
既に作業を終えて、来ることがなくなったディレクトリは popd
で削除します。単に popd
だけで実行するとカレントディレクトリ(0 番目)がスタックから削除されます。カレントディレクトリがスタックから削除されるので、popd
を実行すると自動的に 1 番目のパス(workspace1/js)に移動することに注意してください。
$ popd
$ dirs
0 ~/workspace1/js # popd によって自動的に workspace1/js に移動することに注意!
1 ~/workspace1/html
0 ~/workspace2/html
1 ~/workspace1/js
2 ~/workspace1/html
popd
単体だと 0 番目の workspace2/html が削除されましたが、0 番目ではなく 1 番目を削除したい場合は popd +1
、2 番目を削除したい場合は popd +2
で削除できます。
スタックに保存せずに移動したい場合
しかし時には、ディレクトリスタックに保存するほど頻繁にアクセスしないようなディレクトリに移動したい場合もあります。そのときは cd
で移動します。ただし cd
だと移動前のカレントディレクトリのパスを上書きしてしまうので、移動前のカレントディレクトリのパスを保持したまま、スタックに保存したくないディレクトリに移動したい場合は以下のようにします。
$ dirs
0 ~/workspace2/html
1 ~/workspace1/js
2 ~/workspace1/html
$ pushd .
0 ~/workspace2/html
1 ~/workspace2/html # 同じパスがコピーされる
2 ~/workspace1/js
3 ~/workspace1/html
$ cd temp # スタックに保存したくないディレクトリに移動
$ dirs
0 ~/workspace2/html/temp # ここから 1 番目に戻るときは popd すればスタックから削除される
1 ~/workspace2/html # ここは残った状態
2 ~/workspace1/js
3 ~/workspace1/html
cd
で移動しても 0 番目はカレントディレクトリなので一時的には保存されてしまいますが、popd
すればスタックから削除しつつ、前のディレクトリに戻ることができます。
エイリアスの設定
さて、ここまでの説明では、dirs
を実行したときに、左に番号が表示され、各パスが 1 行ごと表示されていますが、これは実際にはオプションをつけて dirs -v
としなければいけません。単に dirs
と入力すると、各パスがすべて 1 行で表示されてしまう上に、番号が表示されないので、とても不便です。でも dirs -v
と毎回入力するのも面倒くさい…そんなときはエイリアスの出番です。.bashrc
(zsh の場合は .zshrc
)に以下の一行を付け足します。.bashrc
(.zshrc
)はホームディレクトリの隠しファイルです。
alias dirs='dirs -v'
追加して保存したら .bashrc を再読込します。
$ source ~/.bashrc
これで、dirs
と入力するだけで番号が表示されるようになりました!
まとめ
- スタックを確認するには
dirs
- スタックにパスを保存するには
pushd
- スタックからパスを削除するには
popd
-
pushd
単体では、1 番目のディレクトリに移動する -
popd
単体では 0 番目(カレントディレクトリ)に移動する - 2 番目のディレクトリに移動したいときには
pushd +2
(popd
も同じ) - スタックに保存したくないときは
cd
で移動する -
dirs
はエイリアスを設定すると便利