Mir sind bisher zwei Hauptmethoden bekannt:
Ausdrücklich: Klammern um eine Liste von Befehlen setzen
Implizit: jeder Befehl in einer Pipeline
Gibt es noch weitere Möglichkeiten, entweder explizit oder implizit, Untershells in der Bash zu erstellen?
Antwort1
Aus man bash
:
- Wenn ein Kommando durch den Kontrolloperator beendet wird
&
, führt die Shell das Kommando im Hintergrund in einer Untershell aus. Die Shell wartet nicht auf die Beendigung des Kommandos und der Rückgabestatus ist 0. - Ein Coprozess ist ein Shell-Befehl, dem das
coproc
reservierte Wort vorangestellt ist.
Ein Coprozess wird asynchron in einer Subshell ausgeführt, als ob der Befehl mit dem Steueroperator & beendet worden wäre. - Integrierter Shell-
complete
Befehl: Wenn er mit der-C command
Option aufgerufen wird,command
wird er in einer Subshell-Umgebung ausgeführt und seine Ausgabe wird als mögliche Vervollständigung verwendet. - Befehlsersetzung, mit Klammern gruppierte Befehle und asynchrone Befehle werden in einer Subshell-Umgebung aufgerufen, die ein Duplikat der Shell-Umgebung ist.
Antwort2
Es hängt davon ab, was Sie mit „Subshell“ meinen. Und möglicherweise verfehlen Sie den Punkt in Ihrem Punkt „jeder Befehl in einer Pipeline“.
Jedes Mal, wenn Sie laufenbeliebig(externes) Programm (d. h. ein Skript oder eine binäre ausführbare Datei, im Gegensatz zu einem integrierten Shell-Programm), sofern Sie nicht verwenden , führen Sie es in einem Unterprozess (oder mehreren Unterprozessen) aus. Die Shell verzweigt sich und führt das Programm aus. erstellt keine Untershell, genauso wenig wie und alleine tun.exec program
ls | wc
ls
wc
Das Interessante ist, dass die Einbeziehung in eine Pipeline dazu führen kann,eine Shell eingebautin einer Subshell laufen lassenBetrachten Sie dieses Beispiel:
$ lesen v Katze # Dies ist eine vom Benutzer eingegebene Eingabe. $ echo "$v" Katze $ echo cougar | v lesen $ echo "$v" Katze
Der zweite read v
Befehl wird in einer Subshell ausgeführt, da er Teil der echo cougar | read v
Pipeline ist. Daher cougar
geht der Wert verloren und $v
behält seinen ersten Wert.
Ebenso Befehle wie
$ echo foo | cd /
$ cd / | cat
$ echo foo | exit
$ exit | cat
Beeinflussen Sie nicht die Haupt-Shell.