MacOS – .profile is not loaded on non-login /bin/sh

bashcommand linemacosterminal

The problem is in the title, but let me add few details here.

I am running on OS X 10.10.5 (14F27). Using default Terminal.app.


Content of config files

Content of /etc/profile

echo " # reading /etc/profile"
# System-wide .profile for sh(1)

if [ -x /usr/libexec/path_helper ]; then
    eval `/usr/libexec/path_helper -s`
fi

if [ "${BASH-no}" != "no" ]; then
    [ -r /etc/bashrc ] && . /etc/bashrc
fi

Content of /etc/bashrc

echo " # reading /etc/bashrc"
# System-wide .bashrc file for interactive bash(1) shells.
if [ -z "$PS1" ]; then
   return
fi

PS1='\h:\W \u\$ '
# Make bash check its window size after a process completes
shopt -s checkwinsize
# Tell the terminal about the working directory at each prompt.
if [ "$TERM_PROGRAM" == "Apple_Terminal" ] && [ -z "$INSIDE_EMACS" ]; then
    update_terminal_cwd() {
        # Identify the directory using a "file:" scheme URL,
        # including the host name to disambiguate local vs.
        # remote connections. Percent-escape spaces.
    local SEARCH=' '
    local REPLACE='%20'
    local PWD_URL="file://$HOSTNAME${PWD//$SEARCH/$REPLACE}"
    printf '\e]7;%s\a' "$PWD_URL"
    }
    PROMPT_COMMAND="update_terminal_cwd; $PROMPT_COMMAND"
fi

Content of ~/.profile

echo " # reading ~/.profile"
...

Content of ~/.bashrc

echo " # reading ~/.bashr"
...
source /etc/profile
...

Content of ~/.bash_profile

echo " # reading ~/.bash_profile"
source ~/.profile
source ~/.bashrc

Output of calling sh and bash

So here is output of invoking sh.

$ sh
sh-3.2$ 

sh --login
 # reading /etc/profile
 # reading /etc/bashrc
 # reading ~/.profile
d12frosted:~ d12frosted$ 

$ bash
 # reading ~/.bashr
 # reading /etc/profile
 # reading /etc/bashrc
d12frosted:~ d12frosted$ 

$ bash --login 
 # reading /etc/profile
 # reading /etc/bashrc
 # reading ~/.bash_profile
 # reading ~/.profile
 # reading ~/.bashr
 # reading /etc/profile
 # reading /etc/bashrc
d12frosted:~ d12frosted$ 

As you can see, when calling sh – it doesn't load any configurations. Is something broken in my environment or it's expected?

Best Answer

This is expected sh only loads ~/.profile when it is a login shell.

From Bash reference manual

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.

When invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first attempts to read and execute commands from /etc/profile and ~/.profile, in that order. The --noprofile option may be used to inhibit this behavior. When invoked as an interactive shell with the name sh, Bash looks for the variable ENV, expands its value if it is defined, and uses the expanded value as the name of a file to read and execute. Since a shell invoked as sh does not attempt to read and execute commands from any other startup files, the --rcfile option has no effect. A non-interactive shell invoked with the name sh does not attempt to read any other startup files.

Of you want bash running as sh to use ~/.profile when not a login shell (e.g. keep current environment) use

env ENV=$HOME/.profile /bin/sh