sudo nodeでcommand not foundが表示される件

問題

sudoをつけてnodeを実行するとroot権限で実行できる」というのを聞いて、実際にやってみたら

$ sudo node index.js
sudo: node: command not found

このように「command not found」と表示された。

原因

え? コマンドが見つからないってなんで・・?

sudoを付けずにnodeを実行するときちんと実行されるのに何故なんだ・・?

と思って調べてみたら、どうやら原因は「sudo付きでコマンド実行すると環境変数であるPATHがスーパーユーザーのものに変わるから」だった。

(ただし、このsudoの挙動はLinuxのディストリビューターによって違うらしいです。私の環境はUbuntuでしたが、Ubuntuではこのような挙動になってるらしいです)

 

例えば以下の2つのコマンドを実行してみてほしい。

printenv PATH
sudo printenv PATH

printenvは「環境変数の一覧を表示する」というコマンドで、表示したい環境変数を引数に指定するとそれだけを表示できる。

 

私の環境では以下のような違いが出た。

$ sudo printenv PATH
/usr/local/sbin:
/usr/local/bin:
/usr/sbin:
/usr/bin:
/sbin:
/bin:
/snap/bin
$ printenv PATH
/home/vagrant/.yarn/bin:
/home/vagrant/.config/yarn/global/node_modules/.bin:
/home/vagrant/.nvm/versions/node/v10.14.2/bin:
/usr/local/sbin:
/usr/local/bin:
/usr/sbin:
/usr/bin:
/sbin:
/bin:
/usr/games:
/usr/local/games:
/snap/bin

(※分かりやすいように:で改行して、共通するパスは青で塗りつぶしています)

 

これを見ると、nodeのパスはrootのほうには追加されていない。だから実行できなかったらしい。

解決策

解決策としては、3つくらいあるっぽい。

1つ目

1つ目は

sudo /home/vagrant/.nvm/versions/node/v10.14.2/bin/node index.js

という風に実行するたびにフルパスで書く方法。すると(当たり前だが)うまく動く。

 

だけど毎回フルパスで書くなんて、さすがに面倒すぎるので

sudo $(which node) index.js

という風に書いたほうがよい。

 

whichは指定したコマンドのパスを表示するコマンドで、Linuxでは$()で囲うとそのコマンドの出力結果をコマンドとして使えるという機能があるらしい。

もしくはバッククォーテーション``で囲ってもOK。

つまり、下の3つのコードは同じ結果をもたらす。

#全部おなじ結果
sudo /home/vagrant/.nvm/versions/node/v10.14.2/bin/node index.js

sudo `which node` index.js

sudo $(which node) index.js

2つ目

2つ目は、sudoしたときに一般ユーザーのPATHを引き継ぐ方法。

詳しくはこちら。

sudo時にPATHを引き継ぐ方法

3つ目

3つ目は、パスがすでに通っているフォルダに(今回の例でいうと例えばusr/bin/)にシンボリックリンクを貼る方法。

ln -s /home/vagrant/.nvm/versions/node/v10.14.2/bin/node /usr/bin/

おわり

Ubuntu
スポンサーリンク
この記事を書いた人
penpen

1991生まれ。
WEBエンジニアです。うんちコードなら書けます。

技術スタック:TypeScript/Next.js/Express/Docker/AWS

penpenをフォローする
penpenをフォローする
penpenメモ

コメント

タイトルとURLをコピーしました