Was für ein Link zu / bin / systemctl ist / sbin / reboot?

8

Dumme Frage hier. Ich sehe, das /sbin/rebootscheint ein Link zu zu sein /bin/systemctl. Es verhält sich jedoch nicht als "einfacher" Link, da das Aufrufen /bin/systemctlnicht dasselbe ist wie /sbin/reboot.

Auch wenn /bin/systemctles eine rebootOption /sbin/rebootgibt, scheint dies kein einfacher Alias ​​zu sein /bin/systemctl reboot, da beispielsweise reboot --helpeine bestimmte Hilfe gedruckt wird, die mit /bin/systemctl reboot --help(oder /bin/systemctl --help reboot) nicht erreichbar ist.

Was ist dieser Link und wie kann man einen Blick auf seine Definition werfen?

P-Gn
quelle

Antworten:

6

Gute Frage, ich habe die Antwort von @slm ♦ zu Fragen und Antworten zu Unix und Linux gefunden:

Viele Programme verwenden diese Technik, wenn es eine einzelne ausführbare Datei gibt, die ihr Verhalten basierend auf der Ausführung ändert.

In der Regel gibt es im Programm eine Struktur namens case / switch-Anweisung, die den Namen bestimmt, mit dem die ausführbare Datei aufgerufen wurde, und dann die entsprechende Funktionalität für diesen ausführbaren Namen aufruft. Dieser Name ist normalerweise das erste Argument, das das Programm erhält.

Lies die Beispiele...

Während in der ursprünglichen Antwort zwei Beispiele mit C und Perl angegeben sind, ist hier ein Beispiel mit Bash. In Bash $0enthält der Positionsparameter den Namen des ausgeführten Skripts. Erstellen wir also ein einfaches Skript, das aufgerufen program.shund ausführbar gemacht wird:

cat << EOF > program.sh && chmod +x program.sh
#!/bin/bash
echo "I was called as \"\${0##*/}\""
EOF
  • \$entgeht der besonderen Bedeutung von $innerhalb catwährend der Skripterstellung.

  • ${0##*/} gibt während der Skriptausführung nur den Namen der ausführbaren Datei ohne den Pfad aus.

Als nächstes erstellen wir drei symbolische Links zu diesem Skript:

for link in call-{1..3}; do ln -s program.sh $link; done

Abhängig davon, wie wir jetzt program.sh- direkt oder über einen der von uns erstellten symbolischen Links - aufrufen , ist die Ausgabe unterschiedlich:

$ ./program.sh 
I was called as "program.sh"

$ ./call-1 
I was called as "call-1"

$ ./call-2
I was called as "call-2"

$ ./call-3
I was called as "call-3"
pa4080
quelle
2

Wie pa4080 sagt , handelt es sich nur um eine normale symbolische Verknüpfung , die systemctlselbst überprüft, unter welchem ​​Namen sie ausgeführt wurde, um zu entscheiden, welche Aktion ausgeführt werden soll. Dies kann mit jedem Mechanismus erreicht werden, der bewirkt, dass dieselbe ausführbare Datei unter mehreren Namen ausgeführt wird. In der Praxis wird dies durch die Verwendung von Symlinks oder Hardlinks erreicht . Auf GNU / Linux-Systemen wie Ubuntu werden zu diesem Zweck am häufigsten Symlinks verwendet.

In Ubuntu Releases mit systemd (derzeit alle umfassen unterstützte Versionen außer 14.04 LTS, die verwendet Upstart ), nicht nur den rebootBefehl , sondern auch die halt,poweroff , runlevel, shutdown, und telinitBefehle sind alle Symlinks /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

Die genauen Aktionen, systemctldie basierend auf dem Namen ausgeführt werden, den Sie zum Ausführen verwenden, sowie andere Möglichkeiten, wie Sie diese Aktionen angeben können, werden in dieser hervorragenden Antwort von JdeBP auf Was ist der Unterschied zwischen diesen Befehlen zum Herunterfahren eines Linux-Servers? auf Unix.SE . Wie es erklärt, dienen diese Befehle (außer runlevel) als Abkürzung für systemctl isolate ...Befehle, ...die durch unterschiedliche Ziele ersetzt wurden.

Falls Sie interessiert sind, befindet sich der C-Code, der berücksichtigt, welchen Namen Sie bei der systemctlEntscheidung, welche Aktion ausgeführt werden soll, aufgerufen haben, in der in parse_argvdefinierten Funktion systemctl.c, die derzeit in Zeile 6972 dieser Datei beginnt. Um es zu finden, können Sie suchen nach:

static int parse_argv(int argc, char *argv[]) {

Die relevanten Teile umfassen den größten Teil dieser Funktion, aber alles ähnelt in etwa diesem Fragment, setzt sich ähnlich fort, jedoch mit unterschiedlichem Code für jede Zeichenfolge und mit einigen anderen Überprüfungen und Verzweigungslogiken:

                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")) {

Andere Beispiele von Befehlen , die untersuchen , wie sie (manchmal) aufgerufen wurden anders handeln umfassen vim, die anders verhält , wenn laufen , wie vim, ex, view, gvim, gview, und einige andere; ipsiehe diese Frage ; gksusiehe diese Frage ; less, das sein Aussehen ändert, wenn es benannt wirdmore (aber Sie können im Gegensatz zu Ubuntu trotzdem bidirektional scrollen more); busybox;; und die meisten Shells im Bourne-Stil , wie bashund zsh, die sich automatisch besser mit den POSIX-Anforderungensh kompatibel verhalten, wenn sie als ausgeführt werden sh.

Eliah Kagan
quelle