I'd like to source my .bash_profile (or maybe some other file) whenever I switch to superuser. (.bash_profile is the login rc on Mac OS X, .bashrc is the non-login script, and .profile is a login rc that runs for any shell).

Simply, my .bash_profile makes using a terminal more convenient for me, and on those occasional times when I have to go super, I feel like I'm trying to play a guitar without thumbs. More than that, $PS1 and $PROMPT_COMMAND get exported to the super user, but functions defined in my .bash_profile and used in my $PROMPT_COMMAND do not get exported to that lexical environment.

In particular, I source the git-prompt.sh script in my .bash_profile and use the exported __git_ps1 command in my $PROMPT_COMMAND. Thus, every single prompt line in the superuser shell is preceded by the warning:

bash: __git_ps1: command not found.

Now I technically could modify the system-wide rc in /etc/profile in order to achieve the effect. I could look at $HOME, and if it's my home, then source $HOME/.bash_profile. However, this isn't portable. I would have to modify the /etc/profile on every host in which I'm likely to be working. I want to export this behavior to happen on all hosts on which I work.

Can anyone think of a solution that is completely contained in my own bash profile?

No warnings about becoming a super user are necessary. I know there's sudo, and that it's bad, bad, bad, and I'm morally and intellectually inferior for doing it. :)

Mac OS X's su doesn't have the -c option, which would have been a pretty good solution.


If you su from your $HOME, you could just do

. .bash_profile

Alright. I have something now. It's not pretty, but it does work. The main trick is that I can cause code to be executed in the super user shell by changing $PROMPT_COMMAND in the environment. $PROMPT_COMMAND gets executed right away when switching to the new environment, and su preserves bash environment variables.

Thus, here is the solution I'm using:

alias su="export REAL_HOME=$HOME && export SWITCHING_TO_SU=true && export PROMPT_COMMAND='source $HOME/.bash_profile; $PROMPT_COMMAND' && su"

Now my .bash_profile will be run as soon as I switch to the super user, and it will know two key pieces of information: 1) that it is being run because I am switching to super user, and 2) the location of my real home directory. It can use that information to do anything else it needs to do. In particular, my .bash_profile will reset $PROMPT_COMMAND back to its true value, so that the script gets sourced only when switching to su. At the end of the script, I have

if [[ "$SWITCHING_TO_SU" == 'true' ]]; then
    unset REAL_HOME

A similar trick based on aliasing exit() could be used, I believe, to do something when switching out of super user.

  • I will leave this open in case someone has a better idea. – masonk Aug 25 '13 at 16:04

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.