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
{
bash --login
echo $-
shopt login_shell
logout # use CTRL-D : Note the difference here between 1 and 2
}
#2. Interactive, no-login shell: regular terminal: himBHs
{
bash
echo $-
shopt login_shell
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
echo $-
shopt login_shell
EOF
}
#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:
- /etc/profile
- ~/.bash_profile,
- ~/.bash_login, and
- ~/.profile
It reads and executes commands from all files (if exists) during logout in the following order:
- ~/.bash_logout and
- /etc/bash.bash_logout
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
bash --login
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'
Note: 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.
Note: 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?
using --noprofile
option to disable reading commands from files mentioned above in login shell.
echo "HELLO=WORLD1" >> ~/.bash_profile
bash --login
echo $HELLO
bash --login --noprofile
echo $HELLO
How to control the behavior of no-login shell?
- using
--rcfile
option to specify user-specific rc file
- using
--norc
option to disable reading commands from files mentioned above in no-login shell