One category of shell (Non-interactive, login shell with hBc options) is missing in the accepted answer. It is commonly used unlike the one with hBs options to execute a command in a ssh session. To see, compare 4 and 5. I included it with others.
# Combination of login and interactive shells
#1. Interactive, login shell: himBHs
logout # use CTRL-D : Note the difference here between 1 and 2
#2. Interactive, no-login shell: regular terminal: himBHs
exit # use CTRL-D : Note the difference here between 1 and 2
#3. Interactive, no-login shell: executing commands from standard input - scripts: himBHs
cat <<-EOF > myfile && bash -s < myfile
#4. Non-interactive, login shell - takes commands from standard input - pipes: hBs
echo 'echo $-; shopt login_shell' | ssh localhost
#5. Non-interactive, login shell - executes commands : hBc
ssh localhost 'echo $-; shopt login_shell'
#6. Non-interactive, no-login shell : hBc
bash -c 'echo $-; shopt login_shell'
What is a login Shell?
It reads and executes commands from the first available file (if exists) during login session in the following order:
- ~/.bash_login, and
It reads and executes commands from all files (if exists) during logout in the following order:
- ~/.bash_logout and
Note: The difference in calling login files (only the first available file) and logout files (all files).
echo 'echo "Logging out ... $(date)"' >> ~/.bash_logout
echo 'echo "Logging out from /etc/bash.bash_logout... $(date)"' | sudo tee -a /etc/bash.bash_logout
Ctrl-D # logs out
Note: A confusion always comes up when
~/.bashrc file commands are executed during login shell session. Generally, commands in
~/.bashrc file should not be executed during login shell. However, if it occurs, it is because of
~/.bash_profile file includes
~/.bashrc file in it. Verify your
~/.bash_profile file. This is a common behavior in Fedora based linux distributions.
What is a no-login shell?
It reads and executes commands from user-specific settings file: ~/.bashrc
What is a non-interactive session?
It reads and executes commands from
BASH_ENV variable. It is also a way to control the behavior of non-interactive session.
echo "HELLO=WORLD" > ~/myrc
BASH_ENV=~/myrc bash -c 'echo $BASH_ENV; echo $HELLO'
BASH_ENV must contain full-path of shell-script file.
Note: ssh remote non-interactive shell session does not read
BASH_ENV. Instead, it reads
~/.bashrc file of remote user in remote system.
ssh remote sessions do not execute commands from files mentioned in login shell (~/.bash_profile).
This will not work:
BASH_ENV=~/myrc ssh localhost 'echo $BASH_ENV; echo $HELLO'
ssh remoteuser@localhost 'echo $HELLO'
This will work: Because,
.bashrc belongs to current user who is assumed as remote user, and remote system is assumed as localhost in this example.
echo 'HELLO=WORLD' >> ~/.bashrc
ssh localhost 'echo $HELLO'
How to control the behavior of login shell?
--noprofile option to disable reading commands from files mentioned above in login shell.
echo "HELLO=WORLD1" >> ~/.bash_profile
bash --login --noprofile
How to control the behavior of no-login shell?
--rcfile option to specify user-specific rc file
--norc option to disable reading commands from files mentioned above in no-login shell