As a "login shell", Bash reads and sets (executes) the user's profile from ''/etc/profile'' and one of ''~/.bash_profile'', ''~/.bash_login'', or ''~/.profile'' (in that order, using the first one that's readable!).
When a login shell exits, Bash reads and executes commands from the file ''~/.bash_logout'', if it exists.
Why an extra login shell mode? There are many actions and variable sets that only make sense for the initial user login. That's why all UNIX(r) shells have (should have) a "login" mode.
__**Methods to start Bash as a login shell:**__
* the first character of ''argv[0]'' is ''-'' (a hyphen): traditional UNIX(r) shells start from the ''login'' binary
When Bash starts as an interactive non-login shell, it reads and executes commands from ''~/.bashrc''. This file should contain, for example, aliases, since they need to be defined in every shell as they're not inherited from the parent shell.
The feature to have a system-wide ''/etc/bash.bashrc'' or a similar system-wide rc-file is specific to vendors and distributors that ship //their own, patched variant of Bash//. The classic way to have a system-wide rc file is to ''source /etc/bashrc'' from every user's ''~/.bashrc''.
__**Methods to test for interactive-shell mode:**__
* the special parameter ''$-'' contains the letter ''i'' (lowercase I)
When Bash starts in SH compatiblity mode, it tries to mimic the startup behaviour of historical versions of ''sh'' as closely as possible, while conforming to the POSIX(r) standard as well. The profile files read are ''/etc/profile'' and ''~/.profile'', if it's a login shell.
If it's not a login shell, the environment variable [[syntax:shellvars#ENV|ENV]] is evaluated and the resulting filename is used as the name of the startup file.
After the startup files are read, Bash enters the [[#posix_run_mode | POSIX(r) compatiblity mode (for running, not for starting!)]].
__**Bash starts in ''sh'' compatiblity mode when:**__
* the base filename in ''argv[0]'' is ''sh'' (:!: NB: ''/bin/sh'' may be linked to ''/bin/bash'', but that doesn't mean it acts like ''/bin/bash'' :!:)
==== POSIX mode ====
When Bash is started in POSIX(r) mode, it follows the POSIX(r) standard for startup files. In this mode, **interactive shells** expand the [[syntax:shellvars#ENV|ENV]] variable and commands are read and executed from the file whose name is the expanded value.\\
No other startup files are read. Hence, a non-interactive shell doesn't read any startup files in POSIX(r) mode.
* the environment variable [[syntax:shellvars#POSIXLY_CORRECT|POSIXLY_CORRECT]] is set
==== Quick startup file reference ====
* Eventual system-wide rc-files are usually read when ''~/.bashrc'' would be read (at least Debian GNU/Linux behaves like that)
* Regardless of the system-wide files in ''/etc'' which are always read, Bash usually reads the first file found, when multiple choices are given (for user files in ''~/'')
* on startup, the environment variable [[syntax:shellvars#POSIXLY_CORRECT|POSIXLY_CORRECT]] is set
* the command ''set -o posix''
__**Tests for the POSIX(r) mode:**__
* the variable [[syntax:shellvars#SHELLOPTS|SHELLOPTS]] contains ''posix'' in its list
==== Restricted shell ====
In restricted mode, Bash sets up (and runs) a shell environment that's far more controlled and limited than the standard shell mode. It acts like normal Bash with the following restrictions:
* the ''cd'' command can't be used to change directories
* the variables [[syntax:shellvars#SHELL|SHELL]], [[syntax:shellvars#PATH|PATH]], [[syntax:shellvars#ENV|ENV]] and [[syntax:shellvars#BASH_ENV|BASH_ENV]] can't be set or unset
* command names that contain a ''/'' (slash) can't be called (hence you're limited to ''PATH'')
* filenames containing a ''/'' (slash) can't be specified as argument to the ''source'' or ''.'' builtin command
* filenames containing a ''/'' (slash) can't be specified as argument to the ''-p'' option of the ''hash'' builtin command
* function definitions are not inherited from the environment at shell startup
* the environment variable [[syntax:shellvars#SHELLOPTS|SHELLOPTS]] is ignored at startup