Estou tentando entender por que alguns shells parecem receber um tratamento especial quando chamados com sudo . Por exemplo, parece haver dois comportamentos possíveis:
O grupo "implícito" ( pstree é um filho direto de sudo , sem shell entre):
$ sudo pstree -s $$
systemd───login───bash───sudo───pstree
$ sudo bash -c 'pstree -s $$'
systemd───login───bash───sudo───pstree
$ sudo zsh -c 'pstree -s $$'
systemd───login───bash───sudo───pstree
$ sudo dash -c 'pstree -s $$'
systemd───login───bash───sudo───pstree
O grupo "explícito" (o shell é um filho direto de sudo ):
$ sudo ksh -c 'pstree -s $$'
systemd───login───bash───sudo───ksh───pstree
$ sudo tcsh -c 'pstree -s $$'
systemd───login───bash───sudo───tcsh───pstree
$ sudo fish -c 'pstree -s $fish_pid'
systemd───login───bash───sudo───fish───pstree
Obviamente, parece haver algum tipo de integração acontecendo entre o sudo e alguns shells, mas não encontrei documentação sobre isso. Eu também pesquisei o código-fonte do sudo e do bash , mas também não consegui encontrar nenhuma pista.
Esta outra questão parece relacionada: Por que (...) não gera um novo processo filho quando executado em segundo plano?
Minhas versões de sudo e bash são:
$ sudo --version
Sudo version 1.8.29
...
$ bash --version
GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
...
não, isso não é uma interação entre seu shell e sudo; é que o shell encarregado de executar se substitui pelo comando que você executa!
Você pode remover o sudo de tudo para o mesmo resultado; por exemplo, eu executo um zsh em um terminal alacritty:
nada de bala aqui!
Podemos verificar que é isso que acontece executando
Lá vemos
Então, o primeiro execve é bash sendo chamado, o segundo é bash substituindo-se por pstree – não há literalmente nenhum bash existindo depois disso! Nenhum fork/clone acontece no meio.
Claro, isso só funciona com o último comando em uma cadeia de comando. Se nos substituíssemos pelo comando a ser executado antes, não poderíamos executar nada depois. Na verdade, podemos verificar isso com bastante facilidade:
Veja, aqui o primeiro pstree é executado na verdade em um processo criado pelo bash, o segundo pelo mesmo processo, substituindo o bash.
Substituir o shell pelo programa que ele executa é obviamente bom, em termos de recursos: produzimos todos os arquivos de memória, bloqueios, etc.
Não sei por que alguns shells fazem isso e outros não (eles provavelmente usam
fork
ouclone
para copiar o próprio processo, antesexecve
de 'informar o comando especificado). Possivelmente, é uma otimização que nunca ocorreu aos desenvolvedores (se você tem um shell orgulhosamente rico comofish
, por que proteger alguns kB de RAM um pouco antes? Ninguém tentará gerar 10.000 peixes de um script de shell para executar um comando!) , ou era arquiteturalmente complicado de software introduzir um caso especial, ou era impossível, porque o shell mantém algum controle sobre o processo iniciado e, portanto, ainda precisa existir para poder, por exemplo, receber sinais ou fazer IPC. Claro, alguns shells são simplesmente muito antigos e talvez um pouco simplistas como resultado (o últimoksh
lançamento foi há 10 anos!).