こんにちは,米国データサイエンティストのかめ(@usdatascientist)です.
半月ぶりの更新です.
最近「 $subl コマンドが動きません!」という質問を多くいただきます.ほんと,一週間に10人くらいから問い合わせがくるのでこちらの記事にまとめようと思います.( $subl コマンドを実行する記事はこれとこれとかです)
質問してくれている方の多くが,「PATHを通す」ということをあまり理解されていないようなので,今回は「PATHを通す」という作業をちゃんと理解できるようにわかりやすく解説します.
なお,本記事はMacユーザ向けです.本ブログではMacを推奨してます.↓詳しくはこちら
目次
この記事で学ぶこと
- 環境変数について
- $PATH変数について
- $PATH変数にパスを追加する(つまりPATHを通す)
- Symlinkの貼り方
環境変数について知る
よく「PATHを通す」というフレーズは聞きますが,PATHってなんでしょう?
「PATH」は環境変数です.
・・・・環境変数!?
って感じの人も多いと思うので,まずは「環境変数とは」から解説します.
環境変数というのは,OS上で動くプロセス(基本なんでも,ブラウザもGitもDockerもSublimeも)がデータを共有するための箱だと思ってください.
例えば「AGE」という変数(箱)に「20」という値を入れた「AGE=20」の環境変数を作ってみます.
Terminalを開いて(本ブログではiTerm2を推奨),以下のコマンドを実行してみてください.
1 |
$ export AGE=20 |
これで $AGE という環境変数を作れました.(環境変数において, $ は変数を表す記号
確認してみるには $echo コマンドを使います.
1 2 |
echo $AGE 20 |
ちゃんと「20」が出力されているのがわかります.
さて,この $AGE という環境変数ですが,あらゆるOS上で動くプロセスがこの変数を参照することができます.
実はすでに多くの環境変数が設定されていて,あらゆるプロセスが情報のやりとりに環境変数を利用しています.
Terminalで
1 |
$ env |
と打ってみてください.設定されている全ての環境変数が表示されます.例えば $HOME という環境変数がホームディレクトリのパスになっていたり, $USER という環境変数にユーザ名が入っているのがわかります.
これらの値は当然人によって違いますよね?でも,どのソフトウェアも”HOME”や”USER”という環境変数を探せば,その環境の正しい値を取得することができます.環境変数はそんな風に使われます.
さて, $env の一覧の中に「 $PATH 」があると思います..「PATHを通す」のPATHは環境変数の $PATH だとおもっておけばOKです.
環境変数を永続化する
環境変数は実は,シェルからexitしたりログアウトすると消えます.
試しに新しいタブをTerminalで開いて $echo $AGE と打ってみてください.
先ほど表示していた「20」が表示されないと思います.
$export コマンドで作った環境変数はそのシェル内,もしくは子プロセスのみでしか有効ではありません.では,永続的な変数を作るにはどうすればいいか?
シェルには,「シェルを起動するたびに実行する設定ファイル」なるものがあります.Bashというシェルなら ~/.bash_profile や ~/.bashrc がそれに当たります.zshというシェルなら ~/.zshrc です.( ~/.bash_profile についてはこちらでも出てきています. ~ はホームディレクトリです.)
つまり, ~/.bash_profile に先ほどの export AGE=20 を記述すれば,シェルを起動したら常に実行してくれるので,環境変数を永続化させることができます.
この辺りは,慣れるまでは触らないほうがいいと思います.壊して元に戻らなくなると困るので.
PATH変数は何に使われるのか?
Terminalにあるコマンドが実行されたら,コンピュータはそのコマンドを探しに行きます.
例えば $git コマンドをTerminalで実行したら,コンピュータは「”git”というコマンドが打たれた,gitはどこじゃ!」とコンピュータ内で「gitのプログラム」を探しに行きます.
でも,コンピュータの中にはたくさんのファイルやフォルダがあるので,コンミュータ内全てを探してたらかなり時間がかかりますよね?
そこで $PATH 変数の登場.「 $PATH 変数に登録しているパスだけ探す」のです.そうすることで,コンピュータ全部を探さなくてすみます.
実際に $PATH 変数をみてみましょう
1 2 |
$ echo $PATH /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin |
パスが : で区切られているのがわかります.つまり, : で区切られたこれらのパス配下のプログラムのみを,コマンドで実行された時にそのプログラムを探しに行きます.
なので,もし新しいパスを追加したい時は, ~/.bash_profile などの設定ファイルに export PATH=$PATH:<追加したいPATH> を追記します.( $PATH は変数なので, $PATH:<追加したいPATH> とすることで,自身の $PATH の値に追加する形にになります.)
これをやるのは少し上級です.初学者のうちは触れないのがいいかと思います.
$PATH が壊れると,どのプログラムも実行できなくなりかねないので...本題!’command not found’エラーは,PATHが通ってない.解決策はこれ!
さて,今回は質問が多い「 $subl コマンドが’command not found’というエラーになる」という問題を例として扱っていきます.考え方は基本どれも一緒です.
$subl コマンドがみつからないと言っているということは,つまり「環境変数の $PATH に指定しているパス配下をみてみたけどsublなんてプログラムはなかったよ!」とOSくんは言っているわけです.考えられる解決策は2つあります.
- sublプログラムが入っているところにPATHを通す.(sublは /Applications/Sublime Text.app/Contents/SharedSupport/bin/subl にある.つまり $PATH 変数に /Applications/Sublime Text.app/Contents/SharedSupport/bin/を追加する.)
- すでにPATHが通っているパスに /Applications/Sublime Text.app/Contents/SharedSupport/bin/sublを移動する.(たとえば /usr/local/bin 配下に入れる)
通常,単一のアプリケーションのために,PATHを追加することはしません.それをいちいち $PATH に追加していたら大変なことになります.そのため,1.を実行するのは大量のプログラムがそのパスに入っている場合です.(例えばこちらの記事で紹介したAnacondaは,その中にpythonや多くのパッケージが入っているので,PATHを通します.)
2.については,「必ずTerminalから起動するもの」であればそれでもいいかもしれません.が,例えばSublimeのように,GUIから起動することもあるアプリケーションであれば,/Applications/に入れておくのがベターです.
つまり,sublimeのような単一のアプリケーションなのでPATHをわざわざ通すほどでもないが,プログラムも移動させたくない(1.も2.もやりたくない)ケースでは,「すでにPATHが通っているところにシンボリックリンクを貼る」ということで解決させます.
シンボリックリンク(Symbolic link: 通称symlink)というのは,物理的にはコピーはしないけど,参照先としてリンクを貼るもの(プログラミングでいう参照渡しみたいな感じ)
例えば「 /usr/local/bin の配下にsublというものはないけど, /usr/local/bin/subl を求められたら /Applications/Sublime Text.app/Contents/SharedSupport/bin/subl を参照してね」という風に,参照先を指定することができます.
こうすることで,物理的にファイルを動かすことなく,PATHを通すことができます.
これはよく使う技なので覚えておきましょう.
それでは,実際にSymlinkを貼ってみましょう!
サンプルのフォルダを2つ用意します. $mkdir コマンドを使ってフォルダを作成します.
Terminalで以下のコマンドをそれぞれ実行してみてください.(Desktop以下にフォルダとファイルを作っています.)
1 2 3 4 5 6 7 |
$mkdir -p ~/Desktop/temp/one/two $echo "aaa" > ~/Desktop/temp/one/two/a $echo "bbb" > ~/Desktop/temp/one/two/b $cd ~/Desktop/temp/one/two/ $ls -l -rw-r--r-- 1 username groupname 4B Apr 15 21:40 a -rw-r--r-- 1 username groupname 4B Apr 15 21:40 b |
~/Desktop/temp/one/two/ 配下にaとbというファイルができています.
この ~/Desktop/temp/one/two に対して, ~/Desktop/temp/three というパスにSymlinkを貼ります.
Symlinkの貼り方は $ln -s <target_path> <link_path> です. -s を忘れないようにしましょう.
-sオプションをつけないと,ファイルの”実態”とパスを結びつけます.これをハードリンクと呼び,Symlinkのようにファイル(パス)の名前とパスを結びつけることをソフトリンクと呼びます.・・・とりあえず今は「-sをつける!」と覚えておいてもOKです.
1 2 3 4 5 |
$cd ~/Desktop/temp $ln -s ~/Desktop/temp/one/two three $ls -l drwxr-xr-x 3 username groupname 96B Apr 15 21:52 one lrwxr-xr-x 1 username groupname 34B Apr 15 21:54 three -> /Users/username/Desktop/temp/one/two |
つまり,参照先が ~/Desktop/temp/one/two の ~/Desktop/temp/three というリンクを作ったのです.
どいういうことかわからない人はthreeフォルダ(実際はリンク)に移動して $ls コマンドで中にあるファイルをみてみましょう
1 2 3 |
$ cd three/ $ ls a b |
これは ~/Desktop/temp/one/two のフォルダの中身です.
「$sublコマンドが動かない」問題ではどのようにSymlinkを貼ればいいか
正解はこちらのstackoverflowのAnswerにある通り,
1 |
$ ln -s /Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl /usr/local/bin/. |
です.
しかし,気をつける点が2つ.
1. /Applications/ 配下にちゃんとSublime Text.appがあることを確認しましょう.Sublimeのバージョンが違かったり,自分で違う名前で保存している場合は,適宜その名前に変更してください.(ちなみにコマンド内の \ は,スペース文字のエスケープです.)
2. /usr/local/bin にPATHが通ってないとこれでもsublコマンドは使えません.適宜PATHが通っているパスを /usr/local/bin の代わりに指定しましょう.
ここまできたら,こちらの記事で紹介しているのstackoverflowの意味もGithubに上がっている記事の意味も理解できるのではないかと思います.
(追記)Permissionエラーがでる場合
一部の方で,「Permission denied」のエラーが出ている方がいるようです.
そういう場合は,
1 |
$sudo chown -R $(whoami) /usr/local/bin |
のように,該当のフォルダの所有者を自分にしてください.(参考URL)
- chownコマンドで指定したフォルダの所有者を変更することができます.
- -Rで,recursive となり,フォルダ内の全てのファイル,フォルダの所有者を変更することができます.
- $(whoami)で,実行したユーザが返されて,結果,所有者を自分に変更することができます.
まとめ
かなり長くなりましたが,まとめると,
- コンピュータはPATHが通っているところしかコマンドを探しに行かない
- PATHが通っているところ=環境変数の $PATH 変数に指定されているパス
- $PATH を更新するには ~/.bash_profile などの,シェルを開くたびに実行される設定ファイルにexportする
- 大抵の場合は, $PATH をいじるのではなくて,Symlinkを貼ることで解決する
- $ls -s <target_path> <link_path> で,Symlinkを貼る
- アクセス権のエラーが出た場合は$sudo chmodコマンドで所有者を変更
今回の内容は,初学者の方にはちょっと難しいかもしれません.
一回で全てを学ぶ必要はないです.3回くらい読んで,何個か自分でSymlinkを作ってみてください.
$PATH 変数を変更するのだけは気をつけてくださいね.間違えると全てコマンドが’not found’になりかねないのでwでも,ちゃんとPATHを理解していたら,自分で直せると思います.
一番気をつけたいのは,よくわからないけどstackoverflowや他の解決コマンドをコピペして実行することだと思います.
これを機にちゃんと理解が深まればいいなと思います.PATHは初学者の人にとってまじでわかりにくいのでw
それでは!!
[…] 【完全解説】Macで「PATHを通す{… […]