which shutdown
retorna
/usr/bin/shutdown
Eu também tentei sudo which shutdown
por precaução ... mas obtive o mesmo resultado.
Eu posso ver isso
lrwxrwxrwx 1 root root 9 Dec 13 03:38 /usr/bin/shutdown -> systemctl
Também posso fazer algo como (desligar a máquina em 2 horas)
sudo shutdown -h +120
Mas se eu tentar algo bobo como isto:
sudo systemctl -h +120
Eu recebo um erro...
Quando emito, shutdown
estou realmente invocando o /usr/bin/shutdown
? Em caso afirmativo, como o link do desligamento para o systemctl realmente funciona?
Resposta curta
Um programa pode saber o nome com o qual foi invocado; ele aprende seu próprio nome examinando
argv[0]
. Isso permite que executáveis idênticos se comportem de maneira diferente sob nomes diferentes ( exemplo ) ou que um único executável se comporte de maneira diferente quando chamado por meio de links simbólicos com nomes diferentes ( exemplo ).No seu caso, o
systemctl
executável real sabe se está sendo invocado comosystemctl
oushutdown
algo assim. Ele ajusta seu comportamento de acordo.Detalhes adicionais
A matriz de argumentos é definida pelo processo pai. É uma convenção (não um requisito estrito) que
argv[0]
é o nome. Os pais podem ou não seguir a convenção. Quando você executasystemctl
oushutdown
a partir de um shell, o shell é o pai e segue a convenção; em geral, os shells seguem a convenção.Um exemplo em que a convenção não é seguida é o comportamento de
login
(e ferramentas que tentam imitá-la):login
usa um traço inicial no argumento zero para informar a um shell filho que ele deve ser um shell de login. Vamos supor que o shell de login seja Bash. No shellecho "$0"
irá mostrar a você-bash
, apesar do nome do executávelbash
. Este traço inicial é outra convenção.Você pode executar
systemctl
com um nome arbitrário. Alguns nomes são especiais, eles mudam o comportamento desystemctl
, isso é deliberadamente para suportar links simbólicos como o que você observou. No meu Debian 12 estes são (entre outros)shutdown
erunlevel
. Você não precisa criar um link simbólico ou uma cópia para passar um arbitrárioargv[0]
parasystemctl
, você pode usarexec -a
o Bash.Exemplos de uso arbitrário
argv[0]
(Os exemplos presumem
systemctl
que podem ser acessados via$PATH
. Forneça o nome do caminho completo, se necessário.)Na verdade, você pode usar um link simbólico para
systemctl
(como o seushutdown
) e ainda assim passar um arbitrárioargv[0]
. Exemplo:Consertando seu "comando idiota"
Seu "comando idiota"
pode ser corrigido assim:
Aqui o link simbólico nomeado
shutdown
não é usado (pode não existir), o executávelsystemctl
é invocado diretamente; ainda assim ele se comporta comoshutdown
porque passamos o nome correto (shutdown
) comoargv[0]
.