login shell (bash) - how to we invoke a login shell
Solution 1
Programs like SSH, sudo
, su
, etc., start the shell using the exec
family of system calls. And these system calls allow the calling program to specify every argument, including the function. For example, using sudo
to start a login shell:
$ strace -fe execve -o sudo.log sudo -i
root:~ $ echo $0
-bash
root:~ $ logout
$ grep bash sudo.log
19124 execve("/bin/bash", ["-bash"], [/* 31 vars */]) = 0
19140 execve("/bin/ls", ["ls", "/etc/bash_completion.d"], [/* 40 vars */]) = 0
As can be seen in the first execve
call, the array of arguments passed to bash
is just ["-bash"]
- so argument zero is -bash
.
Solution 2
This is easy to replicate with zsh
, which allows the appropriate argument to the exec(3)
call to be specified via ARGV0
:
% ARGV0=-bash bash
-bash-4.1$ ps o cmd --pid=$$
CMD
-bash
-bash-4.1$ exit
% ARGV0=imnotaduck bash
$ ps o cmd --pid=$$
CMD
imnotaduck
$ exit
%
In C, as done by login(1)
, the code would run something along the lines of:
execlp("/usr/local/bin/bash", "-bash", ..., (char *) 0)
to insert the hyphen into the process name. This can be confirmed by either running login
and bash
under strace
, or by inspecting the source code for login
.
Related videos on Youtube
Noob
Updated on September 18, 2022Comments
-
Noob over 1 year
I know what is a login shell and the difference between a login shell and a non-login shell.
But what puzzles me is how it is invoked. It is said that a login shell is invoked with a
-
as argument 0.How can we pass an argument to a shell that is being invoked, then argument 0 is the name of the shell itself?
# -bash -bash: -bash: command not found
Okay nevermind
# bash --login # echo $0 # bash
I still don't see a
-bash
.Only when I SSH in, then I am able to see a
-bash
when issuingecho $0
. But back to my original question,- how does Unix/Linux create a login shell ?
- What is the "thing" that creates a login shell during the login process? If it is a "login" process that invokes the bash shell during login, how does it pass argument 0 as
-
to the bash shell?