TECHBLOGスキルブログ

pushdとpopdについて

2020.07.29

はじめに

ユニトラストの我妻です。先日スクリプトファイルに記述されていたpushd/popdについて、これ何ですかとの質問を受けたので簡単にまとめておきます。

pushd,popdとはナニモノなのか

pushdとpopdは基本的にセットで使われることが多く、ディレクトリー間移動(正しくはディレクトリスタックの操作)に使われるコマンドです。
DOSやBashなど多くのコマンドラインインタプリタに組み込みコマンドとして使われており、WindowsやUNIX系OS等多くのシステムで使うことができます。
ディレクトリ移動ならcdコマンドで十分じゃないかとも思えますが、pushd/popdはディレクトリ移動の履歴の保持と取り出し(スタック)ができるのがメリットです。
スタックとはデータ構造の一種で後入れ先出し(Last In First Out)の特徴を持ちます。
pushdが移動前のディレクトリ情報を保持してディレクトリ移動を行い、popdが最後に保持したディレクトリ移動の履歴を取り出してディレクトリ移動を行います。

Lifo_stack

このディレクトリの履歴をスタックする特徴がとくに複雑な階層構造を行き来するフレームワークのセットアップ等で役に立ちます。

pushd,popdの使い方

sampleProject
    |-- dirA
    |   |-- child001
    |   |   |-- file0001
    |   |   |-- file0010
    |   |   |-- file0011
    |   |   `-- file0100
    |   |-- child002
    |   |   |-- file0001
    |   |   |-- file0010
    |   |   |-- file0011
    |   |   `-- file0100
    |   `-- child003
    |       |-- file0001
    |       |-- file0010
    |       |-- file0011
    |       `-- file0100
    |-- dirB
    |   |-- child010
    |   |   |-- file0001
    |   |   |-- file0010
    |   |   |-- file0011
    |   |   `-- file0100
    |   |-- child020
    |   |   |-- file0001
    |   |   |-- file0010
    |   |   |-- file0011
    |   |   `-- file0100
    |   `-- child030
    |       |-- file0001
    |       |-- file0010
    |       |-- file0011
    |       `-- file0100
    `-- dirC
        |-- child100
        |   |-- file0001
        |   |-- file0010
        |   |-- file0011
        |   `-- file0100
        |-- child200
        |   |-- file0001
        |   |-- file0010
        |   |-- file0011
        |   `-- file0100
        `-- child300
            |-- file0001
            |-- file0010
            |-- file0011
            `-- file0100

上記のディレクトリ構成をサンプルとしてpushd/popdの挙動をディレクトリスタックの中身とあわせて確認してみましょう。

# ディレクトリスタックには現在のディレクトリ情報しか書き込まれていない
[root@1a24cddd4795 sampleProject]$ dirs -v
 0  ~/user/sampleProject
[root@1a24cddd4795 sampleProject]$ pushd dirB/child010
[root@1a24cddd4795 child010]$ dirs -v
 0  ~/user/sampleProject/dirB/child010
 1  ~/user/sampleProject
[root@1a24cddd4795 child010]$ pushd ../child020/
[root@1a24cddd4795 child020]$ pushd ../../dirC/child300/
# ディレクトリスタックを表示すると履歴が新しい順番に並んでいる
[root@1a24cddd4795 child300]$ dirs -v
 0  ~/user/sampleProject/dirC/child300
 1  ~/user/sampleProject/dirB/child020
 2  ~/user/sampleProject/dirB/child010
 3  ~/user/sampleProject
[root@1a24cddd4795 child300]$ popd
# popした分ディレクトリスタックが削除された
[root@1a24cddd4795 child020]$ dirs -v
 0  ~/user/sampleProject/dirB/child020
 1  ~/user/sampleProject/dirB/child010
 2  ~/user/sampleProject
[root@1a24cddd4795 child020]$ popd
[root@1a24cddd4795 child010]$ popd
[root@1a24cddd4795 sampleProject]$ pwd
/root/user/sampleProject
# ディレクトリスタックが空になった
[root@1a24cddd4795 sampleProject]$ dirs -v
 0  ~/user/sampleProject

cdとpushd/popdの比較

上記のディレクトリ構成を持つプロジェクトルートからsampleProject/dirA/child003で作業を行った後にsampleProject/dirC/child200へ移動し、プロジェクトルートに帰ってくる場合を考えてみます。
cdコマンドだけで記述すると、以下の様になります。

[root@1a24cddd4795 sampleProject]$ pwd
/root/user/sampleProject
[root@1a24cddd4795 sampleProject]$ cd dirA/child003
[root@1a24cddd4795 child003]$ pwd
/root/user/sampleProject/dirA/child003
[root@1a24cddd4795 child003]$ cd ../../dirC/child200/
[root@1a24cddd4795 child200]$ pwd
/root/user/sampleProject/dirC/child200
[root@1a24cddd4795 child200]$ cd ../../
[root@1a24cddd4795 sampleProject]$ pwd
/root/user/sampleProject

一方pushd、popdを使った例としては以下の様になります。

[root@1a24cddd4795 sampleProject]$ pwd
/root/user/sampleProject
[root@1a24cddd4795 sampleProject]$ pushd dirA/child003
[root@1a24cddd4795 child003]$ pwd
/root/user/sampleProject/dirA/child003
[root@1a24cddd4795 child003]$ popd
[root@1a24cddd4795 sampleProject]$ pushd dirC/child200/
[root@1a24cddd4795 child200]$ pwd
/root/user/sampleProject/dirC/child200
[root@1a24cddd4795 child200]$ popd
[root@1a24cddd4795 sampleProject]$ pwd
/root/user/sampleProject

cdで移動する場合はルートディレクトリからのパスを表現するためにどうしても..の記述が必要になってしまいますが、
pushd、popdの場合はプロジェクトのルートディレクトリのような移動の起点となるところをpushdしておけば、popdと書くだけで簡単にプロジェクトルートまで戻れるようになります。

大規模フレームワーク等で5層、6層と階層が深くなるほどひと目でわかりにくくなりますが、pushd、popdを用いることでプロジェクトルートからのシンプルなパス記述を行う事ができるようになります。
pushd、popdの詳細なオプションなどについてはリンクよりリファレンスを参照してください。

参考: GNU Bash Manual 6.8.1 Directory Stack Builtins

記述量が増えればそれだけミスが生まれる確率も上がりますので移動するディレクトリが明確にわかっているならcd、ディレクトリに移動して作業したあとまた元のディレクトリに戻るときはpushd、popd等のようにうまく使い分けができるようにしていきたいですね。


              

OTHER CONTENTSその他のコンテンツ

UNITRUST会社を知る

  • 私たちについて

  • 企業情報

SERVICE事業内容

  • システム開発

  • 自社サービス

CONTACT
お問い合わせ

あなたの「想い」に挑戦します。

どうぞお気軽にお問い合わせください。

受付時間:平日9:00〜18:00 日・祝日・弊社指定休業日は除く

お問い合わせ