On RHEL7 I see a different behaviour with startup scripts when I su to a user with /bin/sh or /bin/bash as the shell, despite the fact that /bin/sh points to /bin/bash

I've got the following scripts set up for the user:


echo Hello from .profile


# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc

# User specific environment and startup programs


export PATH

echo Hello from .bash_profile


# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc

# Uncomment the following line if you don't like systemctl's auto-paging feature:

# User specific aliases and functions
echo Hello from .bashrc

Now when I su and specify /bin/bash I get the following output.

[batwad@hellodave ~]$ sudo su -s /bin/bash my_user
Hello from .bashrc
[my_user@hellodave batwad]$

Does this mean .bash_profile wasn't executed? After all, I don't see "Hello from .bash_profile"

Now when I su and specify /bin/sh (which links to /bin/bash anyway) I get the following output.

[batwad@hellodave ~]$ sudo su -s /bin/sh my_user

No echoes and a different shell prompt. What gives?


Following redseven's answer I tried adding -l and got yet another behaviour!

[bawtad@hellodave ~]$ sudo su -l -s /bin/sh my_user
Last login: Thu Aug 16 11:44:38 UTC 2018 on pts/0
Hello from .profile

It's .profile that is used this time! Note the "Last login" part didn't appear on the first try.


The difference in behaviour you see is a standard feature of bash to insure a full compatibility for plain standard Bourne shell environments.

From the mouth of the standard bash man page (type /INVOCATION):

If bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well.

  • 1
    Lesson learned: if you want bash, specify /bin/bash – batwad Aug 20 '18 at 8:05

If you want to use all your settings when you normally have after a login the best way to use the -l (or simple -) option for su:

man su:

       -, -l, --login
       Provide an environment similar to what the user would expect had the user logged in

With the -l option your ~./bash_profile will be used (and your .bashrc as well if it's included into your .bash_profile), otherwise your shell is not a login shell and only the ~/.bashrc will be used.

These are only true if your shell is bash. If you have a different default shell or you specify a different shell with -s option then it all depends how that shell works (which may use or may ignore bash settings). Even if /bin/sh is a symlink to the bash binary it's a different shell, the binary detect which way you started it and starts a different shell not bash.

  • Cool, that yields a different behaviour again! What if I were to expand a little and give the reason for /sbin/nologin' as the user's shell is that it's a service account used to launch an application with an init script, and the su` command is part of that script? Would I want that to be a login shell? – batwad Aug 16 '18 at 11:53

If the bash starts as interactive non-login shell it search for the ~/.bash_bashrc, ~/.bashrc for user-specific configuration and /etc/bash.bashrc for system wide configuration (refer to bash man page).

but if it is run as an interactive login shell(which can be done by appending --login) it first looks for ~/.profileor ~/bash_profile(whatever is availabe.. in your case it hits the ~/.profile so it won't bother reading the ~/bash_profile)for user-specific configuration and /etc/profile for system-wide configs

if you want to source both files add this to your .bashrc file

 if [ -f $HOME/.profile ]; then
     . /etc/profile

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.