シェルでディレクトリを自由自在に飛び回るには

UnixやLinuxのディレクトリを一瞬で移動する pushd、popd、dirs コマンドをマスターする。

便利なのに意外と知られていないcdコマンドの-(ハイフン)オプションとは

LinuxやmacOS(UNIX)のターミナルで最も多く使うコマンドがcdコマンドです。その中で、cd – というコマンドは、UNIX シェルで直前にいたディレクトリに移動するためのコマンドです。例えば、/usr/local/binと/var/logを交互に行ったり来たりする場合の実行例は以下の通りです。$はプロンプトです。

$ cd /usr/local/bin
$ pwd
/usr/local/bin 
$ cd /var/log
$ pwd
/var/log 
$ cd -
/usr/local/bin 
$

上記の例では、最初に /usr/local/bin ディレクトリに移動し、その後 /var/log ディレクトリに移動しています。その後、cd – コマンドを使用して直前にいた /usr/local/bin ディレクトリに移動しています。さらにもう一度、/var/logに移動したい場合も cd – です。このように、cd – コマンドを使用することで、直前にいたディレクトリに簡単に戻ることができます。
これだけ知っていてもかなり便利なのですが、さらに多くのディレクトリを記憶して、自由に移動できるコマンドが、次に紹介するpushdなどです。

pushd/popdの使い方とは

pushd, popd, dirs は、UNIX やLinuxのシェルで使用されるディレクトリをあちこち飛び回るために活用されるコマンドです。具体的には「ディレクトリスタック」を操作します。 ディレクトリスタックとは、現在のディレクトリパスを一時的に保存し、後でそこに戻ることができるようにするためのものです。以下に、それぞれのコマンドの使い方を説明します。

pushd

カレントディレクトリパスをスタックに登録し、指定されたディレクトリに移動します。例えば、カレントディレクトリがホームディレクトリ(~)だったとして、pushd /usr/local と入力すると、/usr/local に移動し、スタックに ~ を登録します。

$ pushd /usr/local
/usr/local ~

スタック内のディレクトリは、番号で参照することができます。

$ dirs -v
0 /usr/local
1 ~

以下のように、cdコマンドで移動すると、スタック番号0のパスが新しいカレントディレクトリに書き換わります。

$ cd bin
$ pwd
/usr/local/bin
$ dirs -v
0 /usr/local/bin
1 ~
$

popd

スタック内に登録されている一番最後に登録したディレクトリを取り出し、それをカレントディレクトリとします。例えば、上記例の続きで popd と入力すると、スタック内の一番最後に登録したディレクトリ(~)に移動します。

$ dirs -v
0 /usr/local/bin
1 ~
$ popd
~
$

dirs

スタック内に登録されているディレクトリを表示します。すでに例で登場していますが、dirs -v と入力すると、スタック内に登録されているディレクトリを番号付きで表示します。

実際の動きで見るpushdたちの使い方

以下を実行し、実験用のワークディレクトリを作成します。

$ cd
$ mkdir works
$ cd works

以下ではディレクトリを10個作成し、すべてのディレクトリをpushコマンドでスタックします。

$ for i in $(seq 0 9)
do
mkdir dir$i
cd dir$i
pushd ..
done
~/works ~/works/dir0
~/works ~/works/dir1 ~/works/dir0
~/works ~/works/dir2 ~/works/dir1 ~/works/dir0
~/works ~/works/dir3 ~/works/dir2 ~/works/dir1 ~/works/dir0
~/works ~/works/dir4 ~/works/dir3 ~/works/dir2 ~/works/dir1 ~/works/dir0
~/works ~/works/dir5 ~/works/dir4 ~/works/dir3 ~/works/dir2 ~/works/dir1 ~/works/dir0
~/works ~/works/dir6 ~/works/dir5 ~/works/dir4 ~/works/dir3 ~/works/dir2 ~/works/dir1 ~/works/dir0
~/works ~/works/dir7 ~/works/dir6 ~/works/dir5 ~/works/dir4 ~/works/dir3 ~/works/dir2 ~/works/dir1 ~/works/dir0
~/works ~/works/dir8 ~/works/dir7 ~/works/dir6 ~/works/dir5 ~/works/dir4 ~/works/dir3 ~/works/dir2 ~/works/dir1 ~/works/dir0
~/works ~/works/dir9 ~/works/dir8 ~/works/dir7 ~/works/dir6 ~/works/dir5 ~/works/dir4 ~/works/dir3 ~/works/dir2 ~/works/dir1 ~/works/dir0

スタックに登録したディレクトリを番号付きで表示します。

$ dirs -v
0 ~/works
1 ~/works/dir9
2 ~/works/dir8
3 ~/works/dir7
4 ~/works/dir6
5 ~/works/dir5
6 ~/works/dir4
7 ~/works/dir3
8 ~/works/dir2
9 ~/works/dir1
10 ~/works/dir0

ここでpushdを実行すると、先頭の二つの順番が入れ替わります。

$ pushd
~/works/dir9 ~/works ~/works/dir8 ~/works/dir7 ~/works/dir6 ~/works/dir5 ~/works/dir4 ~/works/dir3 ~/works/dir2 ~/works/dir1 ~/works/dir0
$ dirs -v
0 ~/works/dir9
1 ~/works
2 ~/works/dir8
3 ~/works/dir7
4 ~/works/dir6
5 ~/works/dir5
6 ~/works/dir4
7 ~/works/dir3
8 ~/works/dir2
9 ~/works/dir1
10 ~/works/dir0

スタック番号10番のdir0にすばやく移動します。このように、スタック番号を指定して任意のディレクトリに移動することができます。

 pushd␣+<番号>

$ pushd +10
~/works/dir0 ~/works/dir9 ~/works ~/works/dir8 ~/works/dir7 ~/works/dir6 ~/works/dir5 ~/works/dir4 ~/works/dir3 ~/works/dir2 ~/works/dir1
$ dirs -v
0 ~/works/dir0
1 ~/works/dir9
2 ~/works
3 ~/works/dir8
4 ~/works/dir7
5 ~/works/dir6
6 ~/works/dir5
7 ~/works/dir4
8 ~/works/dir3
9 ~/works/dir2
10 ~/works/dir1

popdを実行すると、スタック番号0が消えて番号1のdir9に移動します。

$ popd
~/works/dir9 ~/works ~/works/dir8 ~/works/dir7 ~/works/dir6 ~/works/dir5 ~/works/dir4 ~/works/dir3 ~/works/dir2 ~/works/dir1
$ dirs -v
0 ~/works/dir9
1 ~/works
2 ~/works/dir8
3 ~/works/dir7
4 ~/works/dir6
5 ~/works/dir5
6 ~/works/dir4
7 ~/works/dir3
8 ~/works/dir2
9 ~/works/dir1

スタック番号を指定して、スタック上不要なディレクトリを削除することができます。上で番号1の ~/works をスタックから削除してみます。結果は下の通りです。

$ popd +1
~/works/dir9 ~/works/dir8 ~/works/dir7 ~/works/dir6 ~/works/dir5 ~/works/dir4 ~/works/dir3 ~/works/dir2 ~/works/dir1

すべてのスタックを削除したい場合は、dirs -c を実行します。

$ dirs -c
$ dirs -v
0 ~/works/dir9
$

さいごに

pushd をはじめとする、ディレクトリスタックでの移動は、あまり注目されませんが、使い慣れると非常に便利です。皆さんもご活用ください。