How to add/modify PATH for sudo?

I have installed two versions of Python.

  • Python 2.7.14 in /usr/local/bin
  • Python 2.7.5 in /usr/bin.

When I type # python, it uses version 2.7.14 but when I type sudo python, it uses version 2.7.5. How can I make sudo python point to version 2.7.14?

In the output of sudo env | grep PATH, /usr/local/bin appears before /usr/bin but still it is picking up Python from /usr/bin.

PATH=/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

When I type sudo su to enter into the root shell, it gives me python 2.7.14 but in the same session if I type sudo python, it gives me python 2.7.5.

I went through this question but the accepted answer doesn't answer how to ensure sudo uses the correct path.

Here is how the secure path looks like:

secure_path = /usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

Solution 1:

This is definitely a sudo and GNU/Linux question, not really a Python question. When you run sudo foo arg1 arg2 the system first fires up a shell (the one set for root, not you) which is running as root and then "runs" foo arg1 arg2. It is not exactly the same as logging in a root and typing foo arg1 arg2 on the command-line, but close. There are executables which will not allow a sudo-ed user to run or do some things and some additional environment variables set for you which you can see if you run sudo env. You'll see something like:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PS1=%%
PS2=cont>
MAIL=/var/mail/root
LOGNAME=root
USER=root
USERNAME=root
HOME=/root
SHELL=/bin/bash
SUDO_COMMAND=/usr/bin/env
SUDO_USER=my_user
SUDO_USER=spt
SUDO_UID=1000
SUDO_GID=1000
SUDO_COMMAND=/usr/bin/env

And if the shell is bash, the subshell has likely read in the contents of /root/.bashrc if it exists. Additionally, the my_user bash shell will do alias expansion on the first item (i.e., the sudo in sudo foo arg1 arg2) and not the second (foo). So if foo is also an alias, it will not be expanded and therefore the subshell running as root will try to run foo as a literal, and not foo as the alias you created under my_user. There are a few ways to "fix" your issue. One define an alias for sudo with a trailing space:

alias='sudo '

As explained here, this will cause what comes after sodo to be alias-expanded as well before sending it to the subshell to run.

Another option is to edit the /root/.bashrc or equivalent file and do one of several things:

  1. Prepend the location of the desired python to the $PATH variable using something like export PATH=/path/to/foo:$PATH
  2. Define the alias(es) you want it there

Or, you could do something (mildly) risky and lazy but highly effective and just run sudo (cd /root && ln -s /home/my_user/.bashrc) and root will always just source your my_user/.bashrc file.