Why sudo Command Doesn’t Source /root/.bashrc

bashrcsudo

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?

Best Answer

.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'.

Related Question