Bashシェルのpushdとpopdを使いこなしてディレクトリ移動を効率化する方法
pushdコマンドとpopdコマンドは、Bashシェルに組み込まれている機能で、ディレクトリに「しおり」を挟むようにマークを付け、ハードドライブ上の場所を素早く行き来できるようにするものです。ターミナルはコンピュータ内を移動する驚くほど高速な手段だと、すでに実感している方も多いでしょう。わずか数回のキー入力で、ハードドライブのどこへでも、外部ストレージやネットワーク共有先にもアクセスできます。しかし、複数のディレクトリを行ったり来たりする作業や、ファイルシステムの中で「迷子」になってしまったときには、そのスピードが失われてしまいます。まさにそうした問題を解決してくれるのが、pushdとpopdなのです。
pushdの基本
最も基本的な使い方において、pushdはcdコマンドとよく似ています。あるディレクトリから別のディレクトリへ移動するだけのコマンドです。例えば、oneというディレクトリがあり、その中にtwoというサブディレクトリ、さらにその中にthreeというサブディレクトリがあるとします。現在の作業ディレクトリがoneであれば、cdコマンドでtwoやthreeなど、任意の場所へ移動できます。
$ pwd
one
$ cd two/three
$ pwd
three
同じ操作をpushdでも行えます。
$ pwd
one
$ pushd two/three
~/one/two/three ~/one
$ pwd
three
最終的な結果はcdと同じですが、pushdには重要な違いがあります。移動先のディレクトリと移動元のディレクトリが両方表示されるのです。これが「ディレクトリスタック」であり、pushdをユニークな存在にしている要素です。
スタックとは何か
コンピュータ用語における「スタック」とは、要素の集合体を指します。このコマンドの文脈では、pushdコマンドで最近訪れたディレクトリが要素となります。履歴やパンくずリストのようなものだと考えると分かりやすいでしょう。
pushdを使えばファイルシステム中を自由に移動でき、そのたびに以前の場所と新しい場所がスタックに追加されていきます。
$ pushd four
~/one/two/three/four ~/one/two/three ~/one
$ pushd five
~/one/two/three/four/five ~/one/two/three/four ~/one/two/three ~/one
スタックを使ったナビゲーション
一度スタックが構築されれば、それをブックマーク集やファストトラベルのウェイポイントとして活用できます。例えば、ある作業セッションで~/one/two/three/four/fiveというディレクトリ構造の中で多くの作業をしているとしましょう。oneディレクトリに最近訪れたことは覚えているものの、pushdのスタック上のどこにあるのか思い出せないとします。
そんなときは+0(プラス記号とゼロ)という引数を使えば、スタック内のどのディレクトリにも移動せずに、現在のスタックの内容を確認できます。
$ pushd +0
~/one/two/three/four ~/one/two/three ~/one ~/one/two/three/four/five
また、dirsコマンドでもスタックを表示できます。-vオプションを付ければ、各ディレクトリのインデックス番号も確認可能です。
$ dirs -v
0 ~/one/two/three/four
1 ~/one/two/three
2 ~/one
3 ~/one/two/three/four/five
スタックの最初のエントリが現在位置です。いつものようにpwdで確認してみましょう。
$ pwd
~/one/two/three/four
0(現在位置でありスタックの最初のエントリ)から数えて、スタックの2番目の要素が目的の~/oneです。+2オプションを使えば、スタックを前進してそこへ移動できます。
$ pushd +2
~/one ~/one/two/three/four/five ~/one/two/three/four ~/one/two/three
$ pwd
~/one
これで作業ディレクトリが~/oneに変更され、同時にスタックも入れ替わり、新しい場所が先頭に来ます。
スタックを後ろ向きに辿ることもできます。例えば、上記の出力状態から素早く~/one/two/threeへ移動したい場合は、pushdのカウントが0から始まることに注意しながら、1つ戻ればOKです。
$ pushd -0
~/one/two/three ~/one ~/one/two/three/four/five ~/one/two/three/four
スタックへの追加
このようにスタックを行き来し続けることもできますが、スタック自体は最近訪れたディレクトリの静的な一覧のまま保たれます。新しいディレクトリを追加したい場合は、単純にそのパスを指定するだけです。スタックに存在しないディレクトリであれば、期待どおりリストに追加されます。
$ pushd /tmp
/tmp ~/one/two/three ~/one ~/one/two/three/four/five ~/one/two/three/four
一方、すでにスタックに存在するディレクトリを指定すると、重複して2度登録されることになります。
$ pushd ~/one
~/one /tmp ~/one/two/three ~/one ~/one/two/three/four/five ~/one/two/three/four
スタックは素早くアクセスしたいディレクトリの一覧として使われることが多いですが、実際には自分が訪れた場所の正確な履歴になっています。重複した登録を避けたい場合は、+Nや-Nという記法を使う必要があります。
スタックからの削除
スタックは不変のものではありません。pushdで追加し、popdで項目を取り除けます。
例えば、直前にpushdで~/oneをスタックに追加し、~/oneが現在の作業ディレクトリになっているとします。最初の(好みに応じて「0番目の」)要素を削除するには次のようにします。
$ pwd
~/one
$ popd +0
/tmp ~/one/two/three ~/one ~/one/two/three/four/five ~/one/two/three/four
$ pwd
~/one
もちろん、0から数えて任意の要素を削除することもできます。
$ pwd ~/one
$ popd +2
/tmp ~/one/two/three ~/one/two/three/four/five ~/one/two/three/four
$ pwd ~/one
スタックの末尾側から数えて削除することも可能で、こちらも0から始まります。例えば、スタックの最後のディレクトリを削除するには次のようにします。
$ popd -0
/tmp ~/one/two/three ~/one/two/three/four/five
このように使った場合、popdは作業ディレクトリを変更しません。スタックの操作のみを行います。
popdでのナビゲーション
popdを引数なしで実行したときのデフォルトの動作は、スタックの最初(0番目)の項目を削除し、次の項目を作業ディレクトリにするというものです。
これは「クイックチェンジ」コマンドとして最も便利です。例えば、2つの異なるディレクトリで作業をしていて、一瞬別の場所へ立ち寄る必要があるようなケースです。凝った履歴が必要ないなら、ディレクトリスタックのことを意識する必要すらありません。
$ pwd
~/one
$ pushd ~/one/two/three/four/five
$ popd
$ pwd
~/one
pushdとpopdを続けて使う必要もありません。pushdで別の場所を訪れた後、バグの調査やリサーチに3時間没頭したとしても、ディレクトリスタックは辛抱強く待っていてくれます(ターミナルセッションを終了していない限り)。
$ pwd ~/one
$ pushd /tmp
$ cd {/etc,/var,/usr}; sleep 2001
[...]
$ popd
$ pwd
~/one
実務でのpushdとpopdの活用
pushdとpopdコマンドは、意外なほど実用的です。一度覚えてしまえば、あらゆる場面で活用する口実が見つかり、ディレクトリスタックという概念にも自然と慣れていくでしょう。筆者自身、pushdに慣れたことが、概念的に似ていて関係性はないものの捉えどころの難しいgit stashを理解する助けになりました。
シェルスクリプトの中でpushdとpopdを使いたくなるかもしれませんが、一般的には避けるのが賢明です。BashやZsh以外への移植性がなく、スクリプトを読み返すときにも分かりにくくなります(pushd +3よりもcd $HOME/$DIR/$TMPのような書き方の方が明確です)。
こうした注意点を踏まえつつ、BashやZshを日常的に使っているのであれば、pushdとpopdをぜひ試してみてください。きっと日々のターミナル操作がより快適になるはずです。
-
jm-shell – 情報量豊富で自由にカスタマイズできるBashシェル
jm-shellとは jm-shellは、無料で利用できるオープンソースの軽量Bashシェルです。シェル上での操作に関する豊富な情報をリアルタイムに表示するだけでなく、システムの負荷平均やノートパソコンのバッテリー状態など、実用的なシステム情報もひと目で確認できます。 特筆すべき点として、通常のBashが重複を除いたコマンドのみを履歴ファイルに保存するのに対し、jm-shellはすべてのシェル操作をログファイルに記録します。これにより、過去に実行したコマンドを後から確実に検索・確認できます。 さらに、現在のディレクトリがGit、Subversion、Mercurialなどのバージョン管理システ
-
Bashシェル関数入門:実用的な6つのサンプル例で学ぶチュートリアル
Bashシェル関数とは、複数のUNIX/Linuxコマンドをひとつの名前でグループ化し、後からまとめて実行できるようにする仕組みです。Bashシェル関数は通常のUnixコマンドと同じように呼び出すことができ、現在のシェルコンテキスト内で実行されるため、解釈用の新しいプロセスを生成する必要がありません。bashのエイリアス(alias)と関数はどちらも、長いコマンドや複雑なコマンドに対するショートカットを定義するのに役立ちます。しかし、エイリアスでは制御フローや引数の扱いなど、関数ならではの高度な処理を行うことはできません。本記事では、その違いも含めて詳しく解説していきます。この記事は、進行中の