39

I have added a custom path to PATH variable in my /root/.bashrc file

When i do sudo su; echo $PATH, it shows the entry, '/path/to/custom/bins'.

But i do sudo sh -c 'echo $PATH', it shows, /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

The folder paths added in .bashrc file are not visible.

Doesn't sudo command have the same environment as a root user?

3 Answers3

44

.bashrc is a configuration file of bash, only when it's executed interactively. It's only loaded when you start bash, not when you run some other program such as sh (not even if bash is invoked via the name sh). And it's only loaded when bash is interactive, not when it's executing a script or a command with -c.

sudo sh -c 'echo $PATH' or sudo bash -c 'echo $PATH' doesn't invoke an interactive shell, so .bashrc is not involved.

sudo su; echo $PATH runs an interactive instance of root's shell. If that's bash, then ~root/.bashrc is loaded. This snippet executes echo $PATH once this interactive shell terminates, so whatever happens in the interactive shell has no influence on what the snippet prints at the end. But if you type echo $PATH at the prompt of the interactive shell started by sudo su, you will see the value set by ~root/.bashrc.

Since .bashrc is invoked in each interactive shell, not by login shells (not even by interactive login shells, which is a design defect in bash), it's the wrong place to define environment variables. Use .bashrc for interactive bash settings such as key bindings, aliases and completion settings. Set environment variables in files that are loaded when you log in: ~/.pam_environment or ~/.profile.

So set PATH in .profile instead of .bashrc, and either run a login shell with sudo -i 'echo $PATH', or explicitly source .profile with sudo sh -c '. ~/.profile; echo $PATH'.

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
  • 1
    has addressed many relevant points about shells.... thanks.... –  Sep 09 '15 at 02:40
  • 1
    How do I add it to `.profile`? Do you mean `/root/.profile` or `/home/user/.profile`? I tried adding `export PATH=$PATH:/mydir` to both. Didn't work. I tried without `export`, that didn't work either. – falsePockets Jan 22 '19 at 06:06
  • @falsePockets Didn't work for what? You should ask a new question and explain exactly what you're doing. – Gilles 'SO- stop being evil' Jan 22 '19 at 07:45
  • 1
    The thing which didn't work is exactly the same thing OP is trying to do. I am trying to add a directory to the PATH of my superuser. I should not ask a new question, since that question would be a duplicate of this question. – falsePockets Jan 23 '19 at 01:09
  • @falsePockets But evidently you aren't doing the same thing to reach the superuser account. And since you didn't say what you're doing, I can't help you other than repeating what's already in my answer. – Gilles 'SO- stop being evil' Jan 23 '19 at 09:11
  • I made it here because when I "sudo su -" vi and everything else is messed up (doesn't clear the screen when exiting, colors not showing, a lot is wrong with the terminal which works as a normal user) This came seemingly out of box with ubuntu, and I'm trying to determine from your reply what my fix would be? If I explicity run bash immediately, everything is good, but it feels like something is wrong. – Dan Chase Dec 16 '19 at 04:38
  • @DanChase These are the symptoms of a wrong value of `TERM`, but `sudo su -` should not change `TERM`. Maybe you're changing `TERM` in `/root/.profile` or `/root/.bashrc` some such, in which case, don't. – Gilles 'SO- stop being evil' Dec 16 '19 at 13:30
  • `/root/.profile` is not loaded either with `sudo command`. – Myridium Apr 16 '21 at 02:53
  • @Myridium Indeed, see the last paragraph of my answer. – Gilles 'SO- stop being evil' Apr 16 '21 at 13:44
18

Look at the -E and -i options. Here is the corresponding excerpt from man sudo:

-E : Indicates to the security policy that the user wishes to preserve their existing environment variables. The security policy may return an error if the user does not have permission to preserve the environment.

-i : Run the shell specified by the target user's password database entry as a login shell. This means that login-specific resource files such as .profile or .login will be read by the shell. If a command is specified, it is passed to the shell for execution via the shell's -c option. If no command is specified, an interactive shell is executed. sudo attempts to change to that user's home directory before running the shell. The command is run with an environment similar to the one a user would receive at log in. The Command environment section in the sudoers(5) manual documents how the -i option affects the environment in which a command is run when the sudoers policy is in use.

AdminBee
  • 21,637
  • 21
  • 47
  • 71
Vinz
  • 2,120
  • 12
  • 16
  • Both options do not solve the issue of loading/sourcing the `~/.bashrc` file. I guess you already knew that, but this is to inform other people passing by. – adamency Apr 10 '23 at 22:41
  • Also, you really should put the two manual page excerpts in a quote block, as the way you formatted it makes it seem like it's your take on these options and not a simply copy paste of the manual. – adamency Apr 10 '23 at 22:42
3

You could to sudo bash, which does read the bash startup files as documented in the bash manual page/documentation. Please note, however, that it may not set the HOME environment variable correctly. This can be fixed in the system-wide bash startup file (in /etc, exact location depends on distro) - test whether the $uid is 0.

Ned64
  • 8,486
  • 9
  • 48
  • 86