4

I have a problem related to nodejs. I have nodejs binaries here: ~/node-v8.5.0-linux-x64/ and I have a soft link that I created using: ln -s node-v8.5.0-linux-x64/ node.

In my .bashrc, I have this: export PATH=$PATH:$HOME/node/bin.

node and npm are working great when I'm normally logged in. As both of them are installed in my home, I don't need to be logged in as root to install a package globally.

But I wanted to try; so, I ran:

sudo npm install -g angular-cli
sudo node app.js

and it didn't work.

sudo: node : command not found

I thought maybe the $PATH changes when I use sudo but then I checked it using sudo echo $PATH:

/home/dc/bin:/home/dc/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/dc/node/bin

The shell should know where to go when I type node command, but it seems it doesn't. I also tried -H, -i and -u options for sudo but none of that helps either.

Can someone please explain what's happening here?

  • I think something installation or symbolic link issue, follow this askubuntu.com/questions/49390/… – Nullpointer Sep 13 '17 at 13:16
  • 2
    @Nullpointer Nope. He has node/npm installed in his home directory, which is only part of his own user's $PATH. And the assumption that sudo preserves the $PATH variable is wrong, as detailed in my answer below. – Byte Commander Sep 13 '17 at 13:18
7

No, sudo does not preserve your $PATH environment variable for security reasons. Instead, it gets replaced with a secure_path defined in /etc/sudoers, which you should not change.

$ sudo grep secure_path /etc/sudoers
Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

You think to have verified that the $PATH variable stays the same with your command

sudo echo $PATH

but actually Bash expands variables before starting to execute any (here the sudo) command, which means the line above shows your own $PATH value. To get the one as sudo, use e.g.

sudo bash -c 'echo $PATH'

What you can do is to e.g. resolve the command you want to run (node or npm) in your own user's shell using process substitution with which:

sudo "$(which npm)" install -g angular-cli
sudo "$(which node)" app.js

This first runs which npm or which node as your user, which returns the absolute path of the executables belonging to the specified commands. Then that output is literally inserted into your sudo command, so sudo actually believes it got executed with absolute paths like below, removing the need to look anything up in $PATH:

sudo /home/dc/node/bin/npm install -g angular-cli
sudo /home/dc/node/bin/node app.js

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.