Warum einen Linux-Shell-Befehl mit '&' ausführen?

30

Ich verwende Red Hat Linux Enterprise Version 5. Ich habe festgestellt, dass Benutzer manchmal Befehle mit einigen &Optionen ausführen . Im folgenden Befehl gibt es beispielsweise zwei &Zeichen. Was ist der Zweck von ihnen? Werden sie immer zusammen mit Nohup verwendet?

nohup foo.sh <script parameters> >& <log_file_name> &
George2
quelle

Antworten:

15

Zusätzlich zu den Antworten von Martin, Ash und Kevin wird manchmal ein kaufmännisches Und angezeigt, das mathematisch für ein bitweises UND * verwendet wird :

$ echo $(( 11 & 7 ))
3

Falls Sie mit Bitoperatoren nicht vertraut sind:

11: 1011
 7: 0111
-------- AND
 3: 0011

In jeder Position gibt es ein Ein-Bit in der ersten Zahl UND die zweite Zahl, setzen Sie dieses Bit in der Antwort auf Eins.

* Die Funktion in Kevins Antwort wird als logisches UND bezeichnet.

Um die Antwort von Ash zu erläutern, kann das kaufmännische Und bei Verwendung in der Umleitung die Shell anweisen, einen Dateideskriptor zu kopieren. In diesem Befehl echo "hello" > outputfile 2>&1bewirkt das kaufmännische Und, dass alle Ausgaben, die an den Standardfehler (stderr, Dateideskriptor 2) gesendet werden, an die gleiche Stelle gesendet werden wie die Standardausgabe (stdout, Dateideskriptor 1, Standardeinstellung für die linke Seite von >). Der >& outputfileOperator ist eine Abkürzung für > outputfile 2>&1.

Auch neu in Bash 4 gibt es zwei neue Terminatoren für Klauseln in den caseBefehl ;&und ;;&die beeinflussen , ob ein Fall „fällt durch“ und, wenn ja, ob der nächste Test durchgeführt wird .

Bis auf weiteres angehalten.
quelle
Cool, Dennis! Angenommen, ich verwende das ssh-Terminalprotokoll auf einem Computer und verwende dann das ssh-Terminal, um den Befehl auszuführen (vorausgesetzt, es handelt sich um einen langfristigen Prozess). Wenn ich die Terminalsitzung beende, wird der langfristige Prozess des Befehls korrekt beendet. Und wenn der Befehl auch dann ausgeführt werden soll, wenn ich die Shell beende, sollte ich nohup oder & (am Ende des Befehls) verwenden oder sowohl nohup als auch & verwenden?
George2
1
@ George2: Nein, >& filenamegibt sowohl stdout als auch stderr in dieselbe Datei aus. Wenn Sie nur stderr umleiten möchten (und stdout in Ruhe lassen möchten), tun Sie dies 2> filename. Was Ihre andere Frage betrifft, würden Sie höchstwahrscheinlich beides nohupund verwenden &.
Bis auf weiteres angehalten.
1
@ George2: Wenn Sie den Befehl nicht im Hintergrund ausführen, wird keine Shell-Eingabeaufforderung zurückgegeben, sodass Sie einen logoutoder exit-Befehl ausgeben können .
Bis auf weiteres angehalten.
2
George: Wenn Sie nicht & verwenden, werden Sie nie wieder aufgefordert, etwas anderes zu tun. Das Terminal bleibt hängen, bis der Prozess (was auch immer es ist) beendet oder beendet wird. Das & garantiert, dass der Prozess im Hintergrund läuft. Wenn Sie sich jedoch abmelden, beendet das Betriebssystem alle Ihre Prozesse, wodurch auch Ihr Hintergrundprozess beendet wird. Wenn Sie nohup verwenden , sagen Sie dem Prozess "Ignorieren Sie den Befehl, der Sie beendet".
Martin Marconcini
1
@ George2: Ja. "immun gegen auflegen" == "Vorgang fortsetzen" und "non-tty" == "Terminalkonsolensitzung beenden"
Bis auf weiteres angehalten.
32

In einem Bash-Shell-Skript wird das kaufmännische Und "&" verwendet, um Prozesse zu trennen:

find -name hello &

Dadurch wird der Befehl find gegabelt und im Hintergrund ausgeführt (Sie können ihn jederzeit anhand seiner PID beenden).

Martin Marconcini
quelle
Vielen Dank, Martin, nehme an, ich benutze ssh terminal log in einem Rechner und benutze dann das Terminal des ssh, um den Befehl auszuführen (nehme einen langfristigen Prozess an). Wenn ich dann die Terminalsitzung beende, wird der langfristige Prozess des Befehls korrekt beendet ? Und wenn ich den Befehl mit & im ssh-Terminal ausführe, läuft der Langzeitprozess des Befehls immer noch, richtig?
George2
1
Das ist richtig, George. Hintergrundprozesse sollten fortgesetzt werden, bis sie beendet werden oder Sie sie beenden. Wie bereits erwähnt, benötigen Sie nohup, um zu vermeiden, dass der Prozess beim Abmelden des Benutzers abbricht.
Martin Marconcini
Vielen Dank, Martin! Ich möchte wissen, warum wir sowohl & als auch nohup verwenden müssen und welche einzelnen Funktionen sie haben, mit denen wir das Ziel erreichen, den Befehl auch dann weiter ausführen zu lassen, wenn die Terminalkonsole beendet wird. Ich habe die Manpage für nohup gelesen und es wird erwähnt, dass "einen Befehl ausführen, der immun gegen Hangups ist, mit einer Ausgabe auf ein Nicht-Tty". Ich bin verwirrt, ob das Immun gegen Hangups das ist, was Sie damit meinen, wenn Sie den Befehl weiterhin ausführen lassen, ohne durch das Beenden beeinträchtigt zu werden Terminalkonsole? Wenn ja, denke ich, dass die Verwendung von nohup ausreicht und & nicht erforderlich ist. Irgendwelche Kommentare?
George2
1
Sie müssen Both verwenden. Wenn Sie & nicht verwenden, können Sie auf dem Terminal keine anderen Befehle eingeben. Der beste Weg, es zu sehen, ist es einfach zu versuchen. Ein gutes Beispiel ist ein Befehl, der einige Zeit in Anspruch nimmt, wie beispielsweise find: find -name SomeName /> somefile.txt. Versuchen Sie dies mit nohup und & und sehen Sie die Unterschiede.
Martin Marconcini
Dies ist eine großartige Antwort auf die Frage von nohup: serverfault.com/questions/311593/…
joshperry
26

Warum einen Linux-Shell-Befehl mit '&' ausführen?

So erhalten Sie Ihre Aufforderung umgehend zurück und führen den Prozess im Hintergrund aus.

Welche Funktion haben sie?

Mit nohup kann der Hintergrundprozess fortgesetzt werden, auch nachdem sich der Benutzer abgemeldet hat (oder die initiierende Shell beendet hat).

> & Leitet sowohl die Standardausgabe als auch den Standardfehler in die Protokolldatei um.

& führt das Ganze im Hintergrund aus und gibt Ihnen umgehend eine Rückmeldung.

Erläuterung:

Jeder Linux-Prozess öffnet drei E / A-Kanäle, einen Eingang "stdin", einen Standardausgang "stdout" und einen Standardfehlerausgang "stderr". Sie können für Binärdateien verwendet werden, sind jedoch traditionell Text. Wenn die meisten Programme stdin schließen, werden sie beendet (dies kann vom Programmierer geändert werden).

Wenn die übergeordnete Shell beendet wird, ist stdin für die Kinder geschlossen, und (häufig, normalerweise) werden auch die Kinder beendet. Außerdem erhalten die Kinder das Softwaresignal SIGHUP, das angibt, dass der Benutzer (früher das Modem) "aufgelegt" hat und standardmäßig auch beendet wird. (Beachten Sie, dass ein Programmierer all dies ändern kann, wenn er das Programm schreibt.)

Was nohup also tut, ist, dem Kindprozess eine separate E / A-Umgebung zu geben, die die Ein- und Ausgänge mit etwas verknüpft, das nicht mit der Eltern-Shell verbunden ist, und das Kind vor dem Signal SIGHUP abzuschirmen. Sobald der Benutzer die Verbindung trennt, wird der Nohup-Hintergrundprozess von init (Prozess 1) angezeigt, nicht die Shell des Benutzers.

nohupKann den Job jedoch nicht vollständig ausführen, wenn der Prozess im Vordergrund ausgeführt wird. Wird daher &verwendet, um das Programm im Hintergrund auszuführen, wo es problemlos mit oder ohne angemeldeten Benutzer ausgeführt werden kann.

kmarsh
quelle
Angenommen, ich verwende das ssh-Terminalprotokoll auf einem Computer und verwende dann das ssh-Terminal, um den Befehl auszuführen (vorausgesetzt, es handelt sich um einen langfristigen Prozess). Wenn ich die Terminalsitzung beende, wird der langfristige Prozess des Befehls korrekt beendet. Und wenn der Befehl auch dann ausgeführt werden soll, wenn ich die Shell beende, sollte ich nohup oder & (am Ende des Befehls) verwenden oder sowohl nohup als auch & verwenden?
George2
1
Korrigieren Sie, verwenden Sie sowohl nohup als auch &, um den Vorgang fortzusetzen, nachdem die SSH-Verbindung getrennt wurde.
kmarsh
Vielen Dank Kmarsh! Ich möchte wissen, warum wir sowohl & als auch nohup verwenden müssen und welche einzelnen Funktionen sie haben, mit denen wir das Ziel erreichen, den Befehl auch dann weiter ausführen zu lassen, wenn die Terminalkonsole beendet wird. Ich habe die Manpage für nohup gelesen und es wird erwähnt, dass "einen Befehl ausführen, der immun gegen Hangups ist, mit einer Ausgabe auf ein Nicht-Tty". Ich bin verwirrt, ob das Immun gegen Hangups das ist, was Sie damit meinen, wenn Sie den Befehl weiterhin ausführen lassen, ohne durch das Beenden beeinträchtigt zu werden Terminalkonsole? Wenn ja, denke ich, dass die Verwendung von nohup ausreicht und & nicht erforderlich ist. Irgendwelche Kommentare?
George2
1
Ich bearbeite meine Antwort, um zu antworten.
kmarsh
13

Zusätzlich zu @ Martins Antwort: Die andere Verwendung von kaufmännischem Und ( >&wie oben) ist das Erfassen von beiden stdoutund stderr. Wenn Sie die Ausgabe nur mit '>' in eine Datei umleiten, wird in der Regel nur die Ausgabe mit stdoutfehlenden Fehlern ausgegeben .

Asche
quelle
1. Danke Ash, ich möchte mit Ihnen bestätigen, dass "> & <log file name>" alle stderr und stdout in die Logdatei schreibt, richtig? 2. Und wenn Sie "> <Name der Protokolldatei>" verwenden, wird die gesamte Standardausgabe in die Protokolldatei geschrieben, richtig?
George2
1
@ George: Ja, das stimmt.
Ash
Vielen Dank, Ash! Ich möchte wissen, warum wir sowohl & als auch nohup verwenden müssen und welche einzelnen Funktionen sie haben, mit denen wir das Ziel erreichen, den Befehl auch dann weiter ausführen zu lassen, wenn die Terminalkonsole beendet wird. Ich habe die Manpage für nohup gelesen und es wird erwähnt, dass "einen Befehl ausführen, der immun gegen Hangups ist, mit einer Ausgabe auf ein Nicht-Tty". Ich bin verwirrt, ob das Immun gegen Hangups das ist, was Sie damit meinen, wenn Sie den Befehl weiterhin ausführen lassen, ohne durch das Beenden beeinträchtigt zu werden Terminalkonsole? Wenn ja, denke ich, dass die Verwendung von nohup ausreicht und & nicht erforderlich ist. Irgendwelche Kommentare?
George2
4

Neben der Antwort von Martin und Ash wird manchmal die Verwendung eines &&Tokens angezeigt . Dies wird verwendet, um zu sagen: "Führen Sie den zweiten Befehl genau dann aus, wenn der erste Befehl erfolgreich ausgeführt wurde." Ein gut geschriebener Befehl wird bei Fehlern nicht erfolgreich beendet.

[kevin@box ~]$ ls file && echo removing file && rm file
ls: file: No such file or directory
[kevin@box ~]$ touch file
[kevin@box ~]$ ls file && echo removing file && rm file
file
removing file
[kevin@box ~]$
Kevin M
quelle
Cool, Kevin! Angenommen, ich verwende das ssh-Terminalprotokoll auf einem Computer und verwende dann das ssh-Terminal, um den Befehl auszuführen (vorausgesetzt, es handelt sich um einen langfristigen Prozess). Wenn ich die Terminalsitzung beende, wird der langfristige Prozess des Befehls korrekt beendet. Und wenn der Befehl auch dann ausgeführt werden soll, wenn ich die Shell beende, sollte ich nohup oder & (am Ende des Befehls) verwenden oder sowohl nohup als auch & verwenden?
George2
Entweder würde man arbeiten. NOHUP war der ursprüngliche Weg, den ich mir vorstelle (aber ich vermute es total), aber der Hintergrund funktioniert jetzt. Ein wichtiger Unterschied besteht darin, dass eine interaktive Shell auf einem Remote-System ausgeführt wird. Der NOHUP-Prozess würde im Vordergrund ausgeführt, aber beim Beenden weiter ausgeführt, während der Hintergrundprozess sofort nach dem Auslösen des Befehls zurückgegeben würde. Wenn Sie jedoch versuchen, eine interaktive Shell mit einem im Hintergrund ausgeführten Befehl zu beenden, werden Sie zuerst gewarnt.
Kevin M
2

Martins Antwort ist gut, aber ein bisschen mehrdeutig. Der Befehl wird immer gegabelt und ausgeführt, aber das normale Shell-Verhalten besteht darin, auf den Befehl zu warten, bis er beendet wird. Das kaufmännische Und stellt es in den Hintergrund, damit Sie die Eingabeaufforderung Ihres Terminals erhalten und andere Aktionen ausführen können. Wenn der Prozess Daten an stdout oder stderr ausgibt, wird dies mit dem, was Sie an der Eingabeaufforderung tun, vermischt und kann Sie verwirren. Deshalb leiten Sie dann mit> & /path/to/logfile.txt um.

Als Reaktion auf George2 besteht das normale Verhalten beim Beenden einer Shell darin, das SIGHUP-Signal an alle Prozesse in derselben Prozessgruppe zu senden (im Wesentlichen an das, was Sie erzeugt haben), und diese werden normalerweise beendet. Wenn Sie möchten, dass dies auch nach dem Schließen des Shell-Prozesses fortgesetzt wird, können Sie den Befehl nohup verwenden, damit sie dieses Signal ignorieren und weiter ausgeführt werden. Es gibt einen speziellen Namen für diesen Prozesstyp, der als Daemon-Prozess (ausgesprochen 'Dämon') bezeichnet wird.

Reiche Homolka
quelle
Vielen Dank, Rich! Angenommen, ich verwende das ssh-Terminalprotokoll auf einem Computer und verwende dann das ssh-Terminal, um den Befehl auszuführen (vorausgesetzt, es handelt sich um einen langfristigen Prozess). Wenn ich die Terminalsitzung beende, wird der langfristige Prozess des Befehls korrekt beendet. Und wenn der Befehl auch dann ausgeführt werden soll, wenn ich die Shell beende, sollte ich nohup oder & (am Ende des Befehls) verwenden oder sowohl nohup als auch & verwenden? Und warum?
George2
Hey George, tut mir leid, ich antworte so spät. Ja, wenn Sie die Shell verlassen, wird der langfristige Prozess abgebrochen. Wenn Sie möchten, dass es weiter läuft, müssen Sie sowohl nohup (um es nicht zu beenden, wenn die Shell geschlossen wird) als auch & (um es in den Hintergrund zu stellen, damit Sie Crtl-D ausführen oder Ihre Shell beenden können) ausführen. Sie können sich auch den Befehl setsid ansehen, mit dem Ihr Prozess ausgeführt werden kann, wobei SIGHUP auf etwas andere Weise ignoriert wird.
Rich Homolka
Hervorragende Antwort, erklärt Best Practices für im Hintergrund ausgeführte Shell-gestartete Prozesse.
Marcel Valdez Orozco