2 votes

Comment fonctionne le lien symbolique de l'arrêt vers systemctl?

which shutdown

retourne

/usr/bin/shutdown

J'ai aussi essayé sudo which shutdown juste au cas où... mais j'ai obtenu le même résultat.

Je peux voir que

lrwxrwxrwx 1 root root 9 Dec 13 03:38 /usr/bin/shutdown -> systemctl

Je peux aussi faire quelque chose comme (arrêter la machine dans 2 heures)

sudo shutdown -h +120

Mais si j'essaie quelque chose de farfelu comme ceci:

 sudo systemctl -h +120

Je reçois une erreur...

Quand je lance shutdown, est-ce que j'invoque en fait le /usr/bin/shutdown? Si oui, comment fonctionne alors le lien de shutdown vers systemctl?

2voto

Kamil Maciorowski Points 57004

Réponse courte

Un programme peut connaître le nom sous lequel il a été invoqué ; il apprend son propre nom en examinant argv[0]. Cela permet à des exécutables identiques de se comporter différemment sous des noms différents (exemple) ou à un seul exécutable de se comporter différemment lorsqu'il est appelé via des liens symboliques portant des noms différents (exemple).

Dans votre cas, l'exécutable systemctl sait s'il est invoqué en tant que systemctl, shutdown ou autre chose. Il ajuste son comportement en conséquence.


Détails supplémentaires

Le tableau d'arguments est établi par le processus parent. C'est une convention (pas une exigence stricte) que argv[0] est le nom. Le processus parent peut suivre ou non la convention. Lorsque vous exécutez systemctl ou shutdown à partir d'un shell, le shell est le parent et il suit la convention; en général, les shells suivent la convention.

Un exemple où la convention n'est pas suivie est le comportement de login (et des outils qui tentent de le reproduire) : login utilise un tiret en tête du zéroième argument pour informer un shell enfant qu'il est censé être un shell de connexion. Supposons que le shell de connexion soit Bash. Dans le shell, echo "$0" vous montrera -bash, malgré le fait que l'exécutable s'appelle bash. Ce tiret initial est une autre convention.

Vous pouvez exécuter systemctl avec un nom arbitraire. Certains noms sont spéciaux, ils modifient le comportement de systemctl, c'est délibéré pour prendre en charge des liens symboliques comme celui que vous avez observé. Dans ma Debian 12, il s'agit (entre autres) de shutdown et runlevel. Vous n'avez pas besoin de créer un lien symbolique ou une copie pour transmettre un argv[0] arbitraire à systemctl, vous pouvez utiliser exec -a de Bash.


Exemples d'utilisation d'un argv[0] arbitraire

(Les exemples supposent que <code>systemctl</code> peut être atteint via <code>$PATH</code>. Fournissez le chemin complet si nécessaire.)

bash -c 'exec -a foo      systemctl'        # devrait se comporter comme systemctl classique car foo n'est pas un nom qui modifierait le comportement
bash -c 'exec -a shutdown systemctl --help' # devrait se comporter comme shutdown --help
bash -c 'exec -a runlevel systemctl'        # devrait se comporter comme runlevel

En fait, vous pouvez utiliser un lien symbolique vers systemctl (comme votre shutdown) et transmettre quand même un argv[0] arbitraire. Exemple :

bash -c 'exec -a runlevel shutdown'         # devrait se comporter comme runlevel

Correction de votre "commande loufoque"

Votre "commande loufoque"

sudo systemctl -h +120

peut être corrigée comme ceci :

sudo bash -c 'exec -a shutdown systemctl -h +120'

Ici, le lien symbolique nommé shutdown n'est pas du tout utilisé (il pourrait ne pas exister), l'exécutable systemctl est invoqué directement ; il se comporte quand même comme shutdown car nous transmettons le bon nom (shutdown) comme argv[0].

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X