Como pa4080 diz , é apenas um normal link simbólico e systemctl
em si é o que verifica o nome que foi executado como, a fim de decidir qual ação executar. Esse tipo de coisa pode ser alcançado com qualquer mecanismo que faça com que o mesmo arquivo executável seja executado sob vários nomes; na prática, isso é conseguido através do uso de links simbólicos ou links físicos . Em sistemas GNU / Linux, como o Ubuntu, é mais comum usar links simbólicos para esse propósito.
Nas versões do Ubuntu com systemd (que atualmente inclui todos os suportados versões exceto 14.04 LTS, que usa Upstart ), não apenas o comando reboot
, mas também o halt
, poweroff
, runlevel
, shutdown
e telinit
são todos links simbólicos para /bin/systemctl
:
$ file /sbin/{halt,poweroff,reboot,runlevel,shutdown,telinit}
/sbin/halt: symbolic link to /bin/systemctl
/sbin/poweroff: symbolic link to /bin/systemctl
/sbin/reboot: symbolic link to /bin/systemctl
/sbin/runlevel: symbolic link to /bin/systemctl
/sbin/shutdown: symbolic link to /bin/systemctl
/sbin/telinit: symbolic link to /bin/systemctl
As ações precisas systemctl
realizadas com base no nome usado para executá-las, bem como outras maneiras de especificar essas ações, são explicadas em detalhes em esta excelente resposta por JdeBP para Qual é o diferença entre esses comandos para derrubar um servidor Linux? em Unix.SE . Como explicado, esses comandos (exceto runlevel
) operam como abreviação para comandos systemctl isolate ...
com ...
substituído por destinos diferentes.
Caso esteja interessado, o código C que considera qual nome você usou para invocar systemctl
ao decidir qual ação executar está localizado na função parse_argv
definida em systemctl.c
, que atualmente inicia na linha 6972 desse arquivo. Para encontrá-lo, você pode pesquisar por:
static int parse_argv(int argc, char *argv[]) {
As partes relevantes abrangem a maior parte dessa função, mas tudo se parece com esse fragmento, continuando de forma semelhante, mas com código diferente para cada string, e com algumas outras verificações e lógica de ramificação:
if (strstr(program_invocation_short_name, "halt")) {
arg_action = ACTION_HALT;
return halt_parse_argv(argc, argv);
} else if (strstr(program_invocation_short_name, "poweroff")) {
arg_action = ACTION_POWEROFF;
return halt_parse_argv(argc, argv);
} else if (strstr(program_invocation_short_name, "reboot")) {
Outros exemplos de comandos que examinam como eles foram invocados para (às vezes) agir de forma diferente incluem vim
, que se comporta de maneira diferente quando executado como vim
, ex
, view
, gvim
, gview
e vários outros; ip
, veja esta questão ; gksu
, veja essa pergunta ; less
, que altera sua aparência se for nomeado more
(mas ainda permite rolar bidirecionalmente, ao contrário do Ubuntu more
); busybox
; e mais conchas estilo Bourne , como bash
e zsh
, que se comporta automaticamente de forma mais compatível com os requisitos POSIX para sh
se executado como sh
.