8

Context

You are working on Ubuntu LTS 14.04. You are logged in as the root user. You run the following command:

exec su simple_user -c "/bin/bash /etc/init.d/simple_user_service"

So that the "simple_user_service" is launched with "simple_user" privileges and not root privileges.

Question

It seems that "exec su simple_user -c" doesn't source .bashrc nor .profile nor any other normally sourced file for new interactive shell terminal. I confirmed that by adding this line in simple_user .bashrc file:

export TEST="Hello"

Then in my "simple_user_service" init script:

#!/bin/bash
### BEGIN INIT INFO
# Provides:             test_script
# X-Interactive:        true
# Short-Description:    Test script
### END INIT INFO

echo $TEST

When I execute the script, nothing is printed, but if I execute the following commands:

su simple_user
echo $TEST
> Hello

The TEST variable is set and printed out correctly.

So I was wondering: does "exec su simple_user -c" command source any simple_user profile/bashrc files? If so, is there a way to know which ones?

Thanks a lot for your help!

[Edit - 2 hours later]

Thanks to the answer I received, I understood more accurately 'man bash' instructions. I found this:

   When bash is started non-interactively, to run a shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it  appears  there,  and
   uses the expanded value as the name of a file to read and execute.  Bash behaves as if the following command were executed:
          if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
   but the value of the PATH variable is not used to search for the file name.

It is really interesting as you can set BASH_ENV to a file that runs specific commands each time you use "su simple_user -c" without requiring to load the full interactive logic.

So, before executing su simple_user -c, you can simply do:

export BASH_ENV=~/.bash_script

And set things in your simple_user .bash_script file, like:

export TEST="Hello"

Then when I execute the "simple_user_service" script, "Hello" is properly printed.

It was really usefull for me as I needed this to load all the "rvm" environment (ruby) to run a specific script.

Want to know more?

Why all this trouble?

Because I installed ruby god: http://godrb.com/ to monitore this specific script (a delayed job one).

And I'm using "rvm" to manage different rubies.

And the script automatically drop privileges if necessary by executing exec su application_user -c "/bin/bash application_script"

As god needs to run with root privileges and rvm is only loaded in .bashrc/.profile files, I needed a way to properly load rvm environment in my script. I could simply add the rvm load command in the script, but then my script would have been environment dependant and that was not acceptable.

So I added this in my script before privileges are dropped:

if [ -e "config/BASH_ENV" ]; then
  export BASH_ENV=$(cat config/BASH_ENV)
fi

Thanks to that I can load rvm in the file I set in the config/BASH_ENV file. For instance it could be:

# In config/BASH_ENV file of your rails app:
export BASH_ENV="~/.bash_script"

# In /home/simple_user/.bash_script 
[[ -s "/etc/profile.d/rvm.sh" ]] && . "/etc/profile.d/rvm.sh" # Load RVM function

Then, my script and god work as expected.

I did not explain all those things before getting answers so that readers could focus on the real question.

But as I got a good answer and found a good solution thanks to that, I wrote this edit so that it may be useful to others.

Thanks again!

10

When you do:

su some_user -c 'some_command'    

The some_command will be executed as:

bash -c 'some_command'

Assuming bash is some_user's shell defined in /etc/passwd.

Now when you do bash -c 'some_command' you are basically spawning a non-interactive (and of course non-login) session of bash. As no file is sourced by the shell while in non-interactive mode so no file is being read expectedly.

Note that ~/.profile is sourced in a login, interactive session of bash and ~/.bashrc is sourced in a non-login, interactive session of bash. Also note that Ubuntu sources ~/.bashrc from ~/.profile.

Check the INVOCATION section of man bash to get more idea.

0

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.