I have as script that requires root privileges. I run the script using sudo ./script.sh. Some parts of the script need to actually run as the original user, so I use sudo --user=$SUDO_USER inside the script to do that work. The problem I'm having is that I have some utilities installed for the user, and their path is appended to $PATH in my ~/.profile. I get the feeling that ~/.profile is not executed when running as sudo, confirmed by sudo --user=$SUDO_USER echo $PATH.

I can get around this by sourcing $HOME/.profile, but this doesn't seem like the right solution:

sudo --user=$SUDO_USER source $HOME/.profile; command_i_want_to_run

Should I be appending my $PATH in a different file in order to make it available no matter the context?

  • Can you call the utility with an absolute path in your script? From a security standpoint, it is usually recommended not to rely on $PATH (although many scripts do it), so you would actually adhere to security best practices if you do that. Jan 23 '18 at 1:15
  • I want this script to be flexible enough that it can be called from different users on different systems. On machine the script might live in /home/pete/../bin and another might be in /home/otheruser/.../vendor/bin, for example. But it should be discoverable via $PATH.
    – Pete
    Jan 23 '18 at 18:52

I'm not sure if it depends on local sudoers policy, but at least on my Ubuntu system you can use the sudo -i or --login option to specify a login shell:

 -i, --login
             Run the shell specified by the target user's password data‐
             base entry as a login shell.  This means that login-specific
             resource files such as .profile or .login will be read by the

So for example

$ sudo sudo -u steeldriver sh -c 'echo $PATH'
[sudo] password for steeldriver: 


$ sudo sudo -iu steeldriver sh -c 'echo $PATH'

The reason that bashrc or similar configuration files are not sourced, is that sudo does not run a shell. It actually forks the process and does some other things - so it's not necessarily related to a shell at all. If you want to read this in more detail, search for Process model in man sudo.

I can think of two sensible options that are available to you:

  1. You can tell sudo to use a login shell
  2. You can execute bash using sudo and tell bash to be a login shell

The two achieve the same thing in a slightly different way.

Option 1: sudo --user=baam -i echo '$PATH' will tell sudo to start the default shell of baam and execute echo $PATH. Note the quotes around $PATH in the original command, otherwise it will be expanded before bash sees it.

Option 2: sudo --user=baam bash -c -l 'echo $PATH' will use sudo to execute bash. The -l flag tells bash to act as a login shell, so it will source .profile. This is the better solution in my opinion, because you can also specify another shell that supports the -l flag, such as zsh, so you're more flexible overall.

  • Good answer, but one caveat: if you allow calling bash via sudo, you have to be very careful to craft a sudoers file that does not open a barnhole-sized security hole. And of course you would never want to simply allow "ALL" in a sudoers file (outside of a home-user setting, of course). Jan 23 '18 at 18:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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