Ich habe ein Skript, das ich an einer Stelle teilen möchte, damit zwei Kopien desselben Skripts ausgeführt werden.
Zum Beispiel Ich möchte, dass das folgende Bash-Skript existiert:
echo $$ do_fork() echo $$
Wenn dieses Bash-Skript wirklich existiert, wäre die erwartete Ausgabe:
<ProcessA PID> <ProcessB PID> <ProcessA PID>
oder
<ProcessA PID> <ProcessA PID> <ProcessB PID>
Gibt es etwas, das ich anstelle von „do_fork ()“ setzen kann, um dies zu erhalten Art der Ausgabe oder um das Bash-Skript zu veranlassen, eine C-ähnliche Abzweigung auszuführen?
Antwort
Ja. Das Gabeln wird &
geschrieben:
echo child & echo parent
Was Sie möglicherweise verwirrt, ist, dass $$
ist nicht die PID des Shell-Prozesses, sondern die PID des ursprünglichen Shell-Prozesses. Der Grund dafür ist, dass $$
ist eine eindeutige Kennung für eine bestimmte Instanz des Shell-Skripts: Sie ändert sich während der Ausführung des Skripts nicht und unterscheidet sich von $$
bei jeder anderen gleichzeitigen Ausführung Skript. Eine Möglichkeit, die tatsächliche PID des Shell-Prozesses abzurufen, ist sh -c "echo $PPID"
.
Der Kontrollfluss in der Shell ist nicht der gleiche wie bei C. Wenn in C Sie „d schreibe
first(); fork(); second(); third();
dann ist ein Shell-Äquivalent
after_fork () { second; third; } first; after_fork & after_fork
Die einfache Shell-Form first; child & parent
entspricht dem üblichen C-Idiom
first(); if (fork()) parent(); else child();
&
und $$
existiert und verhält sich in jeder Bourne-Shell und in (t) csh so. $PPID
existierte im ursprünglichen Bourne nicht Shell ist aber in POSIX (also „in Asche, Bash, Ksh, Zsh, …).
Kommentare
- Aber das ' ist im Grunde " Gabel + exec ", nicht nur Gabel.
- @mattdm: Äh?
&
ist Fork, es gibt ' keine Exec. Fork + Exec ist, wenn Sie einen externen Befehl starten. - @mattdm: Ah, ich glaube ich sehe was Cory kommt an. Es gibt ' kein
exec
, aber die beiden Sprachen haben unterschiedliche Kontrollabläufe. - @Gilles: Die Bash Der Steueroperator
&
startet eine Unterschale, in der der angegebene Befehl ausgeführt wird. Gabel + exec. Sie können ' nicht einfach&
ohne vorhergehenden Befehl eingeben. - Nun, wenn " Forking wird geschrieben & " waren eine wahre Aussage, Sie könnten in einer Zeile für sich. Sie können jedoch ' t. ' bedeutet hier nicht " Gabel ". Dies bedeutet, dass " den vorhergehenden Befehl im Hintergrund in einer Unterschale " ausführt.
Antwort
Ja, es heißt Subshells . Shell-Code in Klammern wird als ausgeführt Subshell (Fork). Die erste Shell wartet jedoch normalerweise auf den Abschluss des untergeordneten Elements. Sie können sie mit dem Terminator &
asynchron machen. Sehen Sie sie in Aktion mit etwa dem folgenden:
#!/bin/bash (sleep 2; echo "subsh 1")& echo "topsh"
$ bash subsh.sh
Kommentare
- Die Klammern erstellen eine Unterschale , aber das ' s Fork + wait.
&
ist nur Fork. Wenn Sie mehr als eine Pipeline im untergeordneten Prozess ausführen möchten, ' reicht aus, um geschweifte Klammern zu verwenden (die eine Gruppierung durchführen, ohne einen untergeordneten Prozess zu erstellen):{ sleep 2; echo child; } &
Antwort
Es gibt keine native Bash (oder meines Wissens jede andere typische * nix-Shell) Methode, um dies zu tun. Es gibt viele Möglichkeiten, gegabelte Prozesse zu erzeugen, die etwas anderes asynchron ausführen, aber ich glaube nicht, dass irgendetwas der genauen Semantik des Systemaufrufs fork () folgt.
Der typische Ansatz wäre Wenn Sie $0 $@ &
oder was auch immer tun, werden Sie am Anfang von vorne beginnen und müssen dies tun, damit Ihr Skript der obersten Ebene aus Helfern hervorgeht, die genau die Arbeit erledigen, die Sie aufteilen möchten finde das irgendwie heraus.
Ich beginne tatsächlich über mehrere clevere Möglichkeiten nachzudenken, wie man genau das tun könnte …
Aber , bevor mein Gehirn davon zu sehr mitgerissen wird, denke ich, dass eine ziemlich gute Regel lautet: Wenn Sie versuchen, etwas in eine Shell zu schreiben, wird es voller cleverer Tricks und Sie wünschen sich mehr Sprachfunktionen, Zeit, zu einer echten Programmiersprache zu wechseln .
Kommentare
- Obwohl Ihr Standpunkt gut verstanden ist, ist die Syntax von ' wohl schwierig und es ist ' Da die eleganteren Datenstrukturen und Funktionen von Perl oder Python fehlen, ist bash so real wie es nur geht – in seiner Domäne . Es ist eine domänenspezifische Sprache, und ich würde in vielen Fällen sogar besser argumentieren (prägnanter, einfacher) als zB Python. Können Sie einen Raum voller Systeme verwalten und Python nicht kennen? Ja. Können Sie das tun und wissen nicht, wie man [programmiert]? Ich würde ' nicht versuchen wollen. Nach 30 Jahren Shell-Programmierung sage ich Ihnen, dass ' so real ist, wie es nur geht. Und ja, ich spreche Python. Aber ' verwirren die Jugendlichen nicht.
- Das heißt, technisch mag ich diese Antwort mehr. Zu sagen, dass " & " ist die Antwort an den Benutzer , " gabelt sich an einem Punkt, sodass zwei Kopien desselben Skripts ausgeführt werden. " ist für mich verwirrend. Was " & " gemäß dem Bash-Handbuch tut, ist " … führt den Befehl [angegeben] im Hintergrund in einer Unterschale aus. " Es muss einen Befehl beenden und es handelt sich um eine Verzweigung (technisch) Unter Linux wird ein clone ()) ausgeführt, aber zu diesem Zeitpunkt werden zwei Kopien desselben Skripts nicht ausgeführt.