AFAIK at least the most popular shells use the argv[0] as an indicator whether they should behave as a login or a non-login shell. If argv[0] starts with a '-' the shell (bash and zsh at least) behaves as a login shell. Where is this dash appended to the original argument? Does the shell do it by itself figuring out whether it should be a login shell or not or is it done by login or init somehow?
Consider the following program (name it 'test').
int main (int argc, char *argv[]){
printf("first argument: %s\n", argv[0]);
return 0;
}
If this program is invoked from a shell it says 'First argument: test'. If some shell program e.g. zsh is invoked from a shell, the $0 variable is 'zsh'. However if users default login shell in passwd(5) is defined to zsh, then the $0 variable is '-zsh' after the first login. If I change the user default shell to test, the above program after login still prints 'test', not '-test'.
So, is the argv[0] set by some exec() call (from where) or does the shell set it by itself (based on what condition?).
This question differs from why-we-can-not-see-a-single-hyphen-from-0-on-a-login-shell-invoked-with-logi. It asks the role of dash character and how to change it manually. It does not ask where it is appended to argv[0] in normal use cases. However the most popular answer in the other topic claims login to be responsible of the change of the argv[0]. It still lacks the information about the mechanism. Why does it change zsh to -zsh but not test to -test.
exec
family of functions). That said, it prints-test
for me (tested vialogin
on a TTY,su
and SSH on Arch Linux).argv[0]
will be set by whatever program started the shell, and the mechanism is preceding the first argument string with a-
when callingexecv*(2)
:execl("/bin/bash", "-bash", (void*)0)
. Notice that many programs can start a "login" shell, not just obvious ones likelogin
orsshd
(eg.xterm -ls
). Notably,tmux
will start login shells by default in its windows.bash
also has the-l
and--login
options to start a login shell in addition to parsingargv[0]
.