Docker Linux 技術ログ

【$PATH】パスを通すってどういう意味?何をしているの?

2023年1月5日

今日は仕事でDockerfileを編集して、新しいライブラリをインストールする業務をしていました。

主に、composerをインストールして、composerでライブラリを新規に追加し使用できるようにしていました。

composerをインストールした後、composer install コマンドを実行したところ以下のコメントが表示されました。

・・・
RUN composer install --no-dev
0.257 /usr/bin/env: php: No such file or directory
ERROR: executor failed running [/bin/sh -c composer install --no-dev]: exit code: 127
・・・

2行目の/usr/bin/env: php: No such file or directoryを見るとphpのパスが上手く通っていないことがわかります。

Dockerfileの前半でphpをインストールしたのち、上記のcomposer installコマンドが実行されるのですが、先にインストールされたphpのパスが設定されていないためにcomposerがphpを見つけられずエラーが出ている状態でした。

そこで、下記のとおりcomposer installコマンドの前に、phpのパスを通す(設定)ことで、composerがphpを見つけることができて、エラーを解決することができました。

・・・
ENV PATH $PATH:/usr/bin
RUN composer install --no-dev
・・・

ここで、「パスを通す」というのが、なにをやっていることなのか整理したいと思います。

※ 上記はDockerfileのパスを通すときの書き方ですが、ターミナル上でコマンドを叩いてパスを通す方法も記事内で説明しています。

「パスを通す」とは?

結論から言うと、「パスを通す」とは、環境変数$PATHにプログラムのパス(どこにあるか)を設定することです。
言い換えると、「パスを通す」とは、実行ファイルの居場所をコマンドの実行者(OS)に教えてあげることです。

順番に説明していきます。

lsコマンドがどこからでも実行できる理由

たとえば、lsコマンドについて考えます。(windowsの方はpower shellで実行するコマンドで置き換えて考えください)

lsコマンドは基本的にどこでも実行できると思います。(なぜなら、最初からパスが通っているプログラムだから)

$ ls
Applications      Downloads         Movies            Postman           package-lock.json
Desktop           Google Drive      Music             Public
Documents         Library           Pictures          Puppeteer 

 
$ cd Puppeteer 
$ ls
test             url_list

上記を見ると、homeディレクトリでも、Puppeteerディレクトリでも、lsコマンドが実行できています。

これは、lsコマンドで実行されているプログラム(実行可能ファイル)の「パスが通っている」ためです。

つまり、lsコマンドで実行されるプログラム(実行可能ファイル)が置かれている場所を設定しているため、どこからでも実行することができるのです。

つまりつまり、lsコマンドで実行されるプログラム(実行可能ファイル)が置かれている場所をOSに教えてあげているため、どこからでも実行することができるのです。

lsコマンドのパス(PATH)を確認してみる

まずは、whereisコマンドで、lsコマンドに関わるプログラム(実行可能ファイル = バイナリファイル、以下プログラム)がどこにあるか確認します。

# 以下のコマンドに$は入力しないこと

$ whereis ls
ls: /bin/ls /usr/share/man/man1/ls.1

コマンドの結果をみると、lsコマンドのプログラムls/binの下にあることが分かります。(「どこにあるか」というのを「パス」と言います。)

「whereisコマンド」:指定したコマンドに関連するファイルのパスを表示する

次に、上記のパス(PATH)を、コマンドの実行者(OS)が知っているのかを確認してみます。

環境変数$PATHとは?

結論から言うと、OSは環境変数$PATHにプログラムの場所を記録しています。

つまり、パスを通したプログラムは全てこの環境変数$PATHの中に記録されています。

ちなみに「環境変数」とはOSが設定値などを永続的に保存しておくための変数(数値や文字列などを入れておく箱)です。

「環境変数」:OSが設定値などを永続的に保存しておくための箱

それでは環境変数$PATHの中身を確認してみましょう。

以下のように、echoコマンドを使用して、変数の値を表示します。

# 以下のコマンドに$は入力しないこと

$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

環境変数は、複数の値を持つ場合はコロン(:)で区切られています。(Windowsではセミコロン;)

つまり、上記の場合、環境変数$PATHの中身は次の5つです。

$ echo $PATH
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin

これを見てお気付きかもしれませんが、上記からlsが見当たりません。。。

実は、「パスを通す」というのは「プログラムが置かれている場所を教えること」なので、上記のように「このディレクトリにあるかもよ」という感じで登録されています。

例えば、lsコマンドを実行すると、コマンド実行者のOSは、上記の候補となる場所の中からlsというプログラムを探して、見つけたら実行していきます。

優先順位として、探す順番が決まっていて、左から順に探していくことになります。優先順位は左から順です。(縦に並び替えたやつで言うと、優先順位は上から順です。)

「環境変数の優先順位」:左から順(一番左が一番優先される)

ここで、再度以下の結果を思い出してみましょう。

# 以下のコマンドに$は入力しないこと

$ whereis ls
ls: /bin/ls /usr/share/man/man1/ls.1

lsコマンドのプログラムlsは、/binの下にありました。

そして、OSがプログラムを探す場所は次のとおりです。

# 以下のコマンドに$は入力しないこと

$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

左から3つ目に/binがあります。

これによって、コマンドの実行者(OS)はどこからlsコマンドを叩かれても、プログラムlsを見つけ出しlsコマンドを実行することができるのです。

パスを通す方法は?

それでは、lsコマンドのように「パスを通す」ためには、lsコマンドのように「OSにプログラムが置かれている場所を教える」ためには、どうすればいいのでしょうか?

それは簡単で、これまでの話のとおり、次の手順を踏めばOKです。

  1. プログラムが置かれている場所を確認する。
  2. 環境変数$PATHに探す場所を設定する。(これを「パスを通す」と言う

1. プログラムの場所を確認

これは、whereコマンド、whereisコマンド、findコマンドなど調べ方はたくさんあると思います。

※ 自作のプログラム(実行可能ファイル)であれば、調べるまでもなくどこにあるか、またはどこにでも自由に配置できると思うのでここは割愛して大丈夫です。

ここでは、whereisコマンドで調べる方法を紹介します。

今回はgitコマンドで実行されるプログラムgitがどこにあるか確認したいと思います。(git をインストールしていない人はpwdとかhistoryとかで試してみてください)

# 以下のコマンドに$は入力しないこと

$ whereis git 
git: /usr/bin/git /Library/Developer/CommandLineTools/usr/share/man/man1/git.1
 
$ whereis pwd
pwd: /bin/pwd /usr/share/man/man1/pwd.1
 
$ whereis history
history: /usr/share/man/man1/builtin.1

上記より、それぞれのプログラムがどこに置かれているかが分かります。メモしておきましょう。

(※ すみません。上記のように有名どころはすでにパスが通っていると思います)

2. 環境変数$PATHにパスを設定する(パスを通す)

ターミナル上で環境変数$PATHを設定するときは、次のようにします。

たとえば、上記のgitのパス/usr/binを設定する場合(ほとんどの人が既に登録されていると思うが。。。)

# 以下のコマンドに$は入力しないこと

$ export PATH=$PATH:/usr/bin

# 以下のコマンドで$PATHの中身を確認する
$ echo $PATH

exportコマンドは環境変数を設定するコマンドである。

上記の例のように、PATH=$PATH:/usr/binとすることで、もともと環境変数$PATHに書いてあった内容を消すことなく、$PATHの内容の末尾に:/usr/binを追記することができる。

注意する点としては、パスはプログラム名までは登録しないこと。

あくまでもOSがプログラムを探す場所を環境変数$PATHに登録するので、

今回の例であれば$ export PATH=$PATH:/usr/bin/gitではなく$ export PATH=$PATH:/usr/binとする。

いちいち環境変数にプログラム名まで設定すると管理しづらくなるため注意すること。

パスを通したけどエラーが出るとき

パスを通しても、プログラムが実行されなかったり、パスが通ってないよってエラーが出る場合は以下を確認してみましょう。

  1. パスあっている?
  2. パーミッションは大丈夫?(実行権限ある?)
  3. それはプログラム?実行可能ファイル?(もしかしたらディレクトリかも)

最後に、「LPICの勉強しよう」

今回は「パスを通す」という基本事項について触れてきましたが、業務ではdockerfileを扱っていてのでこの基本事項ですらかなり苦戦しました。

そこで思い出したのは「LPIC」についてです。

私自身、基本情報技術者試験に出題されるような内容はある程度、理解できていると思っていますが、LPICに出題されるようなLinuxファイルシステム構造については理解が足りていないように感じます。

上司にも勧められていたので資格取得駆動で勉強していきたいなと改めて思いました。

  • この記事を書いた人
  • 最新記事

Maita Tomoya / yone

2020.4~Webアプリケーションエンジニアとして都内の企業で働き、空いている時間でブログを運営している29歳男です。本ブログは情報の整理をするため、文章を書く機会を作るために始めました。1記事でも多く「誰かのためになる記事」を書けるように頑張ります!転職前は地方の高校で働いていました。教育関係の記事も定期的に書いていきたいと思います。

-Docker, Linux, 技術ログ