Skip to content

Instantly share code, notes, and snippets.

@togakangaroo
Last active March 18, 2021 17:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save togakangaroo/9c243b0498a63783a07c80c84ce05ed5 to your computer and use it in GitHub Desktop.
Save togakangaroo/9c243b0498a63783a07c80c84ce05ed5 to your computer and use it in GitHub Desktop.

Login shell

Whenever bash/zsh/etc was launched with the --login flag or by the systemd/init process determines whether it is a “login shell” (although because there’s two ways to create this, figuring out if you are in a login shell isn’t 100%.

These will run the first readable profile script they encounter. The specific shell determines where it looks but for (some versions) of bash for example the order is .bash_profile, .bash_login, .profile. This varies by version a bit but isn’t too terribly hard to guess. Also there are logout scripts that will run on shell exit (their names are similar but not completely homoiconic). All this can be disabled with --noprofile

Interactive non-login shell

When launched with -i (which is not short for --interactive but instead a shopt thing) or I believe via just bash/zsh without the -c parameter, This is again not straightforward to test for whether you’re interactive or not. Online people say to check for echo $- containing an i but I’ve found situations where that doesn’t do it.

In this case it will run your rc files, again going through an order which seems to vary slightly but most people just do ~/.bashrc or ~/.zshrc. The specific file that is called can be controlled with --rcfile and disabled by --nonrc. These only work if your shell is actually in interactive mode. Note that if you use the -c parameter but not the -i one, then you will not be in interactive mode. Also note that profile is not called (unless you call it explicitly in your rc or something).

Other stuff

If a shell is both --login and -i interactive then it just seems to be treated as a login shell although this doesn’t seem to be explicitly documented

There seems to be a BASH_ENV that you can set that points to a script file that will be run in…some situations. This doesn’t seem terribly common so I didn’t dig in to much. Not sure if zsh even bothers with this

There is also something around naming bash sh that makes it work in a mode where it tries to be compatible to sh, again didn’t dig in too much

Also keep in mind that environment variables are copied into a process from its parent process. Most (but not all) processes do have a login shell somewhere in their parent call chain so you will see any env variables set there. Many have an interactive (or one that explicitly sourced rc files) shell in their parent chain as well

This chart is useful but not 100% correct

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment