Login and Non-login Shell

In the non-root development for DataStage, in order to launch applications as non-root user, I use su - dsadm with following commands. Later I occassionally notice that badal use su dsadm… So what are the differences?

There are two main shell instance types: interactive and noninteractive, but of those, only interactive shells are of interest because noninteractive shells (such as those that run shell scripts) usually don’t read any startup files.

Interactive shells are the ones that you use to run commands from a terminal, they can be classified as login or non-login. I know there are lots of startup files under each user’s home directory, how do they be called and in what order?

Login Shell

Logging in remotely with SSH will give you a login shell (Because we actually need credentials to login).

You can tell if a shell is a login shell by running echo $0; if the first character is a -, the shell’s a login shell.

1
2
3
# if not sure it's login or non-login, check it
echo $0
-bash

When Bash is invoked as a Login shell:

  1. Login process calls /etc/profile (this is for all users)
  2. /etc/profile calls the scripts in /etc/profile.d/
  3. Login process calls $HOME/.bash_profile, $HOME/.bash_login and $HOME/.profile in order, the first found file is run and rest are ignored, most Linux distributions use only one or two of these four startup files. Notice that $HOME/.bashrc are not in the list, it typically run from one of these files.

Login Shells created by explicitly telling to login, there is a - or -l flag:

1
2
3
4
5
6
7
su -
su -l
su --login
su USERNAME -
su -l USERNAME
su --login USERNAME
sudo -i

Non-login Shell

When bash is invoked as a Non-login shell (for example, you just run bash or sh without login): 如果先ssh进入系统,再运行bash,则就是non-login shell了。

  1. Non-login process(shell) calls /etc/bashrc
  2. then calls $HOME/.bashrc (remember!)

Non-Login shells created using the below commands:

1
2
su
su USERNAME

Of course you can source $HOME/.bashrc in $HOME/.bash_profile files to satisfy both login and non-login shell, for example: add . $HOME/.bashrc in $HOME/.bash_profile (it’s usually there by default setting).

The reasoning behind the two different startup filesystems is that in the old days, users logged in through a traditional terminal with a login shell, then started non-login subshells with windowing systems or the screen program. For the non-login subshells, it was deemed a waste to repeatedly set the user environment and run a bunch of programs that had already been run. With login shells, you could run fancy startup commands in a file such as .bash_profile, leaving only aliases and other “lightweight” things to your .bashrc.

This can explain that if you use non-login like su dsadm, the parent exported environment variables are still there in env scope. But if you run su - dsadm, the parent exported environment variables are gone.

Bash Parameters

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Make bash act as if it had been invoked as a login shell
# 但实际上并不是真正的login shell, echo $0 可知
bash --login
bash -l

# -c: string If the -c option is present, then commands are read from string.
# If there are arguments after the string
# they are assigned to the positional parameters, starting with $0.
# 这就不是interactive shell了
bash -c /tmp/test.sh hello world!

# do not run ~/.bashrc, by default same as `sh`
bash --norc

# 这个只对login shell才有用,不进行任何初始化
bash --noprofile

# specify other script to replace .bashrc
bash --rcfile <path to file>

# do syntax check only
bash -n <script>

Interesting question: How to start a shell in clean

~/.bash_logout will be executed when exit login shell.

Question

Docker or K8s pod init process 会初始化 ~/.bashrc吗? 这个init process 是user login shell呢 还是non-login shell? 应该这么理解: k8s pod或者 docker container运行的时候,是可以设置环境变量的,这些环境变量可以被script 使用. 环境变量是独立于login/non-login这个概念的,只要是bash 环境,则环境变量就可以存在而被使用。这个init process 既不是login,也不是non-login,它就是一个普通的内部的程序而已。

0%