/etc/profile not being sourced for login shells

bashcommand lineenvironment-variables

The -l flag to sh is supposed to source the contents of /etc/profile and other profile scripts like ~/.profile, which generally provide the initial set of environment variables for a login session.

With that in mind, I run the command env -i sh -l -c env and expect to see a fresh environment plus the changes made by /etc/profile. However, /etc/profile is never sourced, despite this being the supposed behaviour of the -l flag. On other non-MacOS systems, this -l flag causes /etc/profile to be loaded correctly.

Why does this not work on MacOS, and how can I ensure that the profile scripts are correctly sourced in the right order as they would be on login? (Note that I do not want an interactive shell session)

Best Answer

Unlike other systems, sh is its own compiled binary as if you called bash --posix. From the Bash Reference Manual:

The POSIX startup files are executed ($ENV) rather than the normal Bash files.

env -i strips every environment variable. Even adding it back as env -i ENV=/etc/profile does not work.

Instead of sh just use bash:

env -i bash -l -c env