The Bourne Again Shell (bash
)
loads and runs various startup files under various conditions. This document attempts to list those files
and describe the conditions and order in which they may be loaded.
Normally, bash loads the following files on startup, depending on whether it is an interactive and/or login shell:
Login shell | Non-login shell | |
---|---|---|
Interactive shell |
|
|
Non-interactive shell |
|
|
When bash is run as sh
:
Login shell | Non-login shell | |
---|---|---|
Interactive shell |
|
|
Non-interactive shell |
|
|
When bash is run in POSIX mode:
Login shell | Non-login shell | |
---|---|---|
Interactive shell |
|
|
Non-interactive shell |
|
|
/etc/profile
~/.bash_profile
, or~/.bash_login
, or~/.profile
$BASH_ENV
/etc/bash.bashrc
~/.bashrc
, or--rcfile 'file'
or--init-file 'file'
$ENV
The following startup files might be loaded under various conditions, in approximately the following order.
/etc/profile
The profile loaded for all users when logging in.
Only loaded if:
- login shell, and
- not POSIX mode, and
- not run with
--noprofile
Sometimes the following are sourced in /etc/profile
:
- Files in
/etc/profile.d/*
- For macOS:
/etc/bashrc
/etc/bashrc_$TERM_PROGRAM
(e.g./etc/bashrc_Apple_Terminal
), sourced in/etc/bashrc
~/.bash_profile
, if exists and not running assh
; otherwise:~/.bash_login
, if exists and not running assh
; otherwise:~/.profile
The profile loaded for the current user when logging in.
Only loaded if:
- login shell, and
- not POSIX mode, and
- not run with
--noprofile
Often sources ~/.bashrc
, as the login shell is typically also
an interactive shell for running commands.
- The file in
BASH_ENV
, if set
Only loaded if:
- not interactive, and
- not POSIX mode, and
- not run as
sh
/etc/bash.bashrc
, if compiled in thebash
source code (e.g. Debian)
The profile loaded for all users in interactive shells for running commands.
Only loaded if:
- interactive, and
- not login shell, and
- not POSIX mode, and
- not run as
sh
, and - not run with
--norc
NOTE: In the bash
source code, the SYS_BASHRC
definition in config-top.h
controls whether /etc/bash.bashrc
will be loaded (if applicable):
/* System-wide .bashrc file for interactive shells. */
/* #define SYS_BASHRC "/etc/bash.bashrc" */
In the current bash
source code,
the SYS_BASHRC
definition is commented out, and this is also true, for example, in the bash
source code for
macOS as of 10.2 (Jaguar).
In contrast, some distros have un-commented this code to enable /etc/bash.bashrc
,
for example, as patched in the bash
source code for Debian as of
3.1 (Sarge).
~/.bashrc
, or the file set by--rcfile
or--init-file
The profile loaded for the current user in interactive shells for running commands.
Only loaded if:
- interactive, and
- not login shell, and
- not POSIX mode, and
- not run as
sh
, and - not run with
--norc
Often sourced from ~/.bash_profile
, so that this profile is also applied to
interactive login shells.
- The file in
ENV
, if set
The profile loaded for POSIX mode shells.
Only loaded if:
- interactive, and
- POSIX mode, or run as
sh
~/.bash_logout
TODO: document this.
/etc/bash.bash_logout
, if compiled in thebash
source code (e.g. Debian)
TODO: document this.
NOTE: In the bash
source code, the SYS_BASH_LOGOUT
definition in config-top.h
controls whether /etc/bash.bash_logout
will be loaded on shutdown (if applicable):
/* System-wide .bash_logout for login shells. */
/* #define SYS_BASH_LOGOUT "/etc/bash.bash_logout" */
In the current bash
source code,
the SYS_BASH_LOGOUT
definition is commented out, and this is also true, for example, in the bash
source code for
macOS as of 10.2 (Jaguar).
In contrast, some distros have un-commented this code to enable /etc/bash.bash_logout
,
for example, as patched in the bash
source code for Debian as of
3.1 (Sarge).
The following variables, commands, options and inputs might directly or indirectly affect which startup files are loaded.
If set, specifies the bash environment file for non-interactive bash
shells
(e.g. those with file input, command input, or
non-terminal input). As usual, this file is only loaded if:
- not interactive, and
- not POSIX mode, and
- not run as
sh
If set, specifies the POSIX/sh
environment file for interactive sh
or POSIX shells.
As usual, this file is only loaded if:
- interactive, and
- POSIX mode, or run as
sh
Sets the shell to POSIX mode.
The following commands might affect which startup files are loaded, compared to running bash
normally.
When bash is run as sh
:
- First, for non-POSIX login shells only, loads the system profile
(
/etc/profile
) and user profile (~/.profile
only), unless run with--noprofile
. - Next, for interactive shells only,
loads the POSIX/
sh
environment file (inENV
, if set). - Finally, the shell enters POSIX mode.
Assuming the user's default shell is bash, the login
command runs a new bash login shell.
When bash is run using the exec
builtin with the -l
option (i.e. exec -l bash
or exec -l sh
),
it runs as a login shell.
Sets the shell to POSIX mode.
Loads the specified user run-command file instead of ~/.bashrc
.
(It is presumed that the last instance of this option in the command will be the one in effect,
but this is not documented.) As usual, this file is only loaded if:
- interactive, and
- not login shell, and
- not POSIX mode, and
- not run as
sh
, and - not run with
--norc
The shell behaves as a login shell.
The system profile (/etc/profile
) and user profile
(~/.bash_profile
, or ~/.bash_login
, or /.profile
) will not be loaded.
The system run-command (/etc/bash.bashrc
) and user run-command
(~/.bashrc
, or --rcfile
, or --init-file
) files will not be loaded.
Sets the shell to POSIX mode.
Specifies a command to run. This causes the shell to run non-interactively.
The shell behaves as an interactive shell. Note that this doesn't prevent
the shell from exiting after running its commands, if that would have occurred without the -i
option.
Causes an argument to the shell to be treated as a positional parameter instead of a file to run. This causes the shell to run interactively instead of running the file non-interactively.
A shell run with no arguments and no non-terminal standard input (i.e. no pipes, no redirections, etc.) will run interactively.
A shell run with at least one argument, and without the -c
or -s
option, will treat the
first argument as the name of a file to run non-interactively, then exit.
(Using the -s
option causes the first argument to be treated as a positional parameter instead of
a file to run, so the shell runs interactively in that case.)
A command can be specified using the -c
option, in which case a new
non-interactive shell runs the command, then exits.
When a shell is run with input from something other than a terminal (for example, from a
pipe or
redirection),
a new non-interactive shell runs the supplied input, then exits.
(In this situation, the -s
option can be used to specify positional parameters.)
The following conditions might affect which startup files are loaded.
Generally, an interactive shell executes commands supplied from terminal input, then continues running, waiting for additional commands from the terminal, until explicitly exited.
Generally, a non-interactive shell executes commands supplied from a file (e.g. shell script), direct command, or non-terminal input (e.g. pipe or redirection), then exits when complete.
The difference in startup files between interactive and non-interactive shells is as follows.
For interactive shells:
- The bash environment file (in
BASH_ENV
) will not be loaded. - The system run-command (
/etc/bash.bashrc
) and user run-command (~/.bashrc
, or--rcfile
, or--init-file
, as appropriate) files will be loaded. As usual, these files are only loaded if:- not login shell, and
- not POSIX mode, and
- not run as
sh
, and - not run with
--norc
- The POSIX/
sh
environment file (inENV
, if set) will be loaded, if in POSIX mode or run assh
.
For non-interactive shells:
- The bash environment file (in
BASH_ENV
, if set) will be loaded. - The system run-command (
/etc/bash.bashrc
) and user run-command (~/.bashrc
, or--rcfile
, or--init-file
) files will not be loaded. - The POSIX/
sh
environment file (inENV
) will not be loaded.
Run a non-interactive shell by supplying commands to be run when invoking the shell. This could be done in one of the following ways. The shell will exit upon completion of the commands.
-
Without the
-c
or-s
options, specify the name of a file to run as the first argument.bash "/path/to/some_script"
Alternatively, add an appropriate shebang (such as
#!/usr/bin/env bash
) to a shell script and invoke it directly."/path/to/some_script"
-
With the
-c
option, specify a command string to run.bash -c 'printf "flags: %s\n" "${-}"'
-
With no arguments (or with arguments using the
-s
option), send text commands to the shell's standard input using pipes, redirections, or some other non-terminal input.echo 'printf "flags: %s\n" "${-}"' | bash
echo 'printf "flags: %s\n" "${-}"' | bash -s "args"
-
Run the shell with no input.
bash
-
Run the shell with arguments, but use the
-s
option to treat the arguments as positional parameters instead of a file to run.bash -s "some_arg"
-
Force the shell to be interactive using the
-i
option. (Note that this doesn't prevent the shell from exiting after the specified commands have completed, if that would have occurred without the-i
option.)bash -i -c 'printf "flags: %s\n" "${-}"'
-
Check if the shell options (
-
) contain thei
flag.case "${-}" in (*"i"*) # Interactive shell. ;; (*) # Non-interactive shell. esac
-
Check if the shell prompt variable (
PS1
) is set.if [ -n "${PS1+set}" ]; then # Interactive shell. else # Non-interactive shell. fi
The difference in startup files between login and non-login shells is as follows, when not in POSIX mode.
For login shells:
- The system profile (
/etc/profile
) and user profile (~/.bash_profile
, or~/.bash_login
, or~/.profile
, as appropriate) will be loaded, unless run with--noprofile
. - The system run-command (
/etc/bash.bashrc
) and user run-command (~/.bashrc
, or--rcfile
, or--init-file
) files will not be loaded.
For non-login shells:
- The system profile (
/etc/profile
) and user profile (~/.bash_profile
, or~/.bash_login
, or~/.profile
) will not be loaded. - For interactive shells only, the system run-command (
/etc/bash.bashrc
) and user run-command (~/.bashrc
, or--rcfile
, or--init-file
, as appropriate) files will be loaded, unless run with--norc
or run assh
.
-
Run the shell with the
--login
or-l
option.bash --login
bash -l
-
Start a new login shell with the
login
command.login
-
Run the shell using the
exec -l
command.exec -l bash
-
Run the shell without using any of the above.
bash
Alternatively, add an appropriate shebang (such as
#!/usr/bin/env bash
) to a shell script and invoke it directly."/path/to/some_script"
-
Check if the command (
0
) begins with a hyphen-minus (-
).case "${0}" in ("-"*) # Login shell. ;; (*) # Non-login shell. esac
-
Check if the
login_shell
shell option is set.if shopt -q login_shell; then # Login shell. else # Non-login shell. fi
If POSIX mode is in effect when a shell is started, then no startup files are loaded,
except for the POSIX/sh
environment file (in ENV
, if set)
for interactive shells only.
-
Run the shell as
sh
. In this case, some startup files are still loaded before the shell enters POSIX mode.sh
Alternatively, add an appropriate shebang (such as
#!/usr/bin/env sh
, assumingsh
is bash) to a shell script and invoke it directly."/path/to/some_script"
-
Run the shell with the
--posix
or-o posix
option.bash --posix
bash -o posix
-
Run the command
set -o posix
orshopt -s -o posix
. Note that this causes the existing shell to switch to POSIX mode, rather than starting a new shell.set -o posix
shopt -s -o posix
-
Set the
POSIXLY_CORRECT
variable. If this is set after the shell is started, note that this causes the existing shell to switch to POSIX mode, rather than starting a new shell.set POSIXLY_CORRECT
-
Check if the
POSIXLY_CORRECT
variable is set.if [ -n "${POSIXLY_CORRECT+set}" ]; then # Bash POSIX mode. else # Not POSIX mode. fi
-
Check if the
SHELLOPTS
variable contains theposix
option.case "${SHELLOPTS}" in ("posix" | "posix:"* | *":posix:"* | *":posix") # Bash POSIX mode. ;; (*) # Not POSIX mode. esac
-
Check if the shell was run as
sh
.case $(basename "${BASH}") in ("sh" | "-sh") # Bash POSIX mode, by virtue of being run as `sh`. ;; (*) # Unknown - could still be in POSIX mode even if not run as `sh`. esac
TODO: document how to use the included debugging scripts.
GNU > Software > All GNU packages > GNU Bash > Documentation > GNU Bash manual > Bash Reference Manual:
- 3 Basic Shell Features
- 4 Shell Builtin Commands
- 4.1 Bourne Shell Builtins
- 4.3 Modifying Shell
Behavior
- 4.3.1 The Set Builtin
-o posix
option
- 4.3.2 The Shopt Builtin
login_shell
option
- 4.3.1 The Set Builtin
- 5 Shell Variables
- 6 Bash Features
- 6.1 Invoking Bash
--init-file
option--login
option--noprofile
option--norc
option--posix
option--rcfile
option-c
option-i
option-l
option-o
option-s
option
- 6.2 Bash Startup Files
- 6.3 Interactive Shells
- 6.11 Bash POSIX Mode
- 6.1 Invoking Bash
GNU > Software > How to get GNU software > Savannah > Savannah Git Hosting > bash.git:
Apple Open Source > Source Browser > bash
- TODO: bash in remote shell
daemon (
rshd
,sshd
) - TODO: bash run as
su
- TODO: real vs. effective UID/GID
- TODO: shutdown files
- TODO: history files
- TODO: readline init files
This document is licensed under a Creative Commons Attribution 4.0 International (CC-BY-4.0) License.
Accompanying source code is licensed under the MIT License.
Copyright © 2020-2021 Chris Tollefson