shell de login (bash) - como invocar um shell de login

3

Eu sei o que é um shell de login e a diferença entre um shell de login e um shell de não-login.

Mas o que me intriga é como ele é invocado. Dizem que um shell de login é invocado com um - como argumento 0.

Como podemos passar um argumento para um shell que está sendo invocado, então o argumento 0 é o nome do próprio shell?

# -bash 
-bash: -bash: command not found

Ok, esqueça ...

# bash --login
# echo $0
# bash

Ainda não vejo um -bash .

Somente quando eu SSH entrar, então eu posso ver um -bash ao emitir echo $0 . Mas voltando à minha pergunta original,

  1. como o Unix / Linux cria um shell de login?
  2. Qual é a "coisa" que cria um shell de login durante o processo de login? Se for um processo de "login" que invoca o shell bash durante o login, como ele passa o argumento 0 como - para o shell bash?
por Noob 13.08.2015 / 20:44

3 respostas

7

Programas como SSH, sudo , su , etc., iniciam o shell usando a família exec de chamadas do sistema . E essas chamadas de sistema permitem que o programa de chamada especifique cada argumento, incluindo a função. Por exemplo, usando sudo para iniciar um shell de login:

$ 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

Como pode ser visto na primeira chamada execve , a matriz de argumentos passada para bash é apenas ["-bash"] - então o argumento zero é -bash .

    
por 13.08.2015 / 21:09
1

Isso é fácil de replicar com zsh , o que permite que o argumento apropriado para a chamada exec(3) seja especificado 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
% 

Em C, como feito por login(1) , o código executaria algo nos seguintes termos:

execlp("/usr/local/bin/bash", "-bash", ..., (char *) 0)

para inserir o hífen no nome do processo. Isso pode ser confirmado executando login e bash sob strace ou inspecionando o código-fonte para login .

    
por 13.08.2015 / 21:09
0

Para fazer o login como usuário usertest, faça (sendo root):

root:~# login usertest
Password: 
usertest:~$ echo $0
-bash
usertest:~$ exit
root:~# _

Essa é a maneira formal pela qual um usuário faz login.

Claro, você pode sempre executar um comando para o qual é $ 0 é alterado:

bash -c 'echo "hello"; echo $0;' mylogthisshell

Que sempre pode ter um traço inicial

bash -c 'echo "hello"; echo $0;' -mylogthisshell
    
por 13.08.2015 / 21:12