Kann jemand anhand einfacher Beispiele erklären, wozu der Befehl exec in Shell-Skripten verwendet wird?
Kann jemand anhand einfacher Beispiele erklären, wozu der Befehl exec in Shell-Skripten verwendet wird?
Antworten:
Die exec
eingebauten Befehlsspiegelfunktionen im Kernel, auf execve
deren Basis eine Familie basiert , die üblicherweise von C aufgerufen wird.
exec
Ersetzt das aktuelle Programm im aktuellen Prozess, ohne fork
einen neuen Prozess zu erstellen. Es ist nicht etwas, das Sie in jedem Skript verwenden würden, das Sie schreiben, aber es ist gelegentlich nützlich. Hier sind einige Szenarien, die ich verwendet habe;
Wir möchten, dass der Benutzer ein bestimmtes Anwendungsprogramm ohne Zugriff auf die Shell ausführt. Wir könnten das Anmeldeprogramm in / etc / passwd ändern, aber vielleicht möchten wir, dass die Umgebungseinstellung aus Startdateien verwendet wird. In (sagen wir) .profile
sagt die letzte Aussage so etwas wie:
exec appln-program
Jetzt gibt es keine Shell mehr, zu der man zurückkehren kann. Selbst wenn es appln-program
abstürzt, kann der Endbenutzer nicht zu einer Shell gelangen, da diese nicht vorhanden ist - exec
sie hat sie ersetzt.
Wir möchten eine andere Shell als die in / etc / passwd verwenden. So dumm es auch scheinen mag, auf einigen Websites können Benutzer ihre Anmeldeshell nicht ändern. Bei einer Site, die ich kenne, haben alle angefangen csh
, und alle haben einfach .login
einen Aufruf an ihre (csh-Startdatei) gesendet ksh
. Während das funktionierte, lief ein streunender csh
Prozess und die Abmeldung war zweistufig, was verwirrend werden konnte. Also haben wir es geändert exec ksh
, indem wir gerade das C-Shell-Programm durch die Korn-Shell ersetzt und alles einfacher gemacht haben (es gibt andere Probleme damit, wie die Tatsache, dass ksh
es sich nicht um eine Login-Shell handelt).
Nur um Prozesse zu speichern. Wenn wir anrufen prog1 -> prog2 -> prog3 -> prog4
usw. und niemals zurückkehren, machen Sie jeden Anruf zu einem Exec. Es spart Ressourcen (zugegebenermaßen nicht viel, sofern es nicht wiederholt wird) und vereinfacht das Herunterfahren.
Sie haben offensichtlich exec
irgendwo verwendet gesehen , vielleicht könnten wir seine Verwendung rechtfertigen, wenn Sie den Code zeigen, der Sie nervt.
Bearbeiten : Ich habe festgestellt, dass meine Antwort oben unvollständig ist. Es gibt zwei Verwendungen von exec
in Shells wie ksh
und bash
- zum Öffnen von Dateideskriptoren. Hier sind einige Beispiele:
exec 3< thisfile # open "thisfile" for reading on file descriptor 3
exec 4> thatfile # open "thatfile" for writing on file descriptor 4
exec 8<> tother # open "tother" for reading and writing on fd 8
exec 6>> other # open "other" for appending on file descriptor 6
exec 5<&0 # copy read file descriptor 0 onto file descriptor 5
exec 7>&4 # copy write file descriptor 4 onto 7
exec 3<&- # close the read file descriptor 3
exec 6>&- # close the write file descriptor 6
Beachten Sie, dass der Abstand hier sehr wichtig ist. Wenn Sie zwischen der fd-Nummer und dem Umleitungssymbol ein Leerzeichen einfügen exec
, wird die ursprüngliche Bedeutung wiederhergestellt:
exec 3 < thisfile # oops, overwrite the current program with command "3"
Es gibt mehrere Möglichkeiten , wie Sie diese, auf KSH Gebrauch verwenden können , read -u
oder print -u
, auf bash
, zum Beispiel:
read <&3
echo stuff >&4
exec gunicorn
dem Supervisor schließlich die richtige PID zurückgibt.
exec
dies für die Umleitung verwendet werden kann:> Wenn kein Befehl angegeben ist, werden alle Umleitungen in der aktuellen Shell wirksam und der Rückgabestatus ist 0. Wenn ein Umleitungsfehler vorliegt, ist der Rückgabestatus 1. Aber wie geht das ? exec
tatsächlich arbeiten, um einen Dateideskriptor zu ändern? Warum wird dieser spezielle Befehl für diese Aufgabe ausgewählt? (Markdown schlägt gerade fehl?)
exec >.\logfilename.log 2>&1
&>
ist eine bash
Erweiterung (siehe man bash
) und Ihr Beispiel entspricht exec >/var/log/userdata.log 2>&1
. Mit anderen Worten, es leitet stdout und stderr in diese Datei um. Die folgenden Befehle erben diese Umleitungen, sofern sie nicht zurückgesetzt werden. Sie werden jedoch ausgeführt.
Nur um die akzeptierte Antwort mit einer kurzen, für Neulinge geeigneten kurzen Antwort zu ergänzen, brauchen Sie sie wahrscheinlich nicht exec
.
Wenn Sie noch hier sind, sollte die folgende Diskussion hoffentlich zeigen, warum. Wenn Sie rennen, sagen Sie,
sh -c 'command'
Sie führen eine sh
Instanz aus und beginnen dann command
als untergeordnetes Element dieser sh
Instanz. Wenn der command
Vorgang abgeschlossen ist, wird auch die sh
Instanz beendet.
sh -c 'exec command'
führt eine sh
Instanz aus, ersetzt diese sh
Instanz dann durch die command
Binärdatei und führt diese stattdessen aus.
Natürlich sind beide in diesem begrenzten Kontext nutzlos; du willst einfach
command
Es gibt einige Randbedingungen, in denen die Shell ihre Konfigurationsdatei lesen oder die Umgebung auf andere Weise als Vorbereitung für die Ausführung einrichten soll command
. Dies ist so ziemlich die einzige Situation, in der exec command
es nützlich ist.
#!/bin/sh
ENVIRONMENT=$(some complex task)
exec command
Dies führt einige Dinge aus, um die Umgebung so vorzubereiten, dass sie das enthält, was benötigt wird. Sobald dies erledigt ist, ist die sh
Instanz nicht mehr erforderlich. Daher ist es eine (geringfügige) Optimierung, die sh
Instanz einfach durch den command
Prozess zu ersetzen , anstatt sh
sie als untergeordneten Prozess auszuführen und darauf zu warten. Beenden Sie sie dann, sobald sie abgeschlossen ist.
Wenn Sie am Ende eines Shell-Skripts so viele Ressourcen wie möglich für einen umfangreichen Befehl freigeben möchten, möchten Sie exec
diesen Befehl möglicherweise als Optimierung verwenden.
Wenn etwas zwingt SieFormal laufen , sh
aber sie wirklich laufen etwas anderes wollen, exec something else
ist natürlich das Problem zu umgehen , die unerwünschte zu ersetzen sh
Instanz (wie zum Beispiel , wenn Sie wirklich Ihre eigene spiffy laufen wollen gosh
statt , sh
aber bei Sie sind , die nicht in /etc/shells
so können Sie Geben Sie es nicht als Ihre Login-Shell an.
Die zweite Verwendung exec
zum Bearbeiten von Dateideskriptoren ist ein separates Thema. Die akzeptierte Antwort deckt das gut ab; Um dies in sich geschlossen zu halten, werde ich nur auf das Handbuch zurückgreifen, exec
wenn eine Umleitung anstelle eines Befehlsnamens folgt.