Der folgende Code beschreibt mein Problem.Übergeben Sie die Ausgabe vom ersten Befehl als Eingabe an den zweiten Befehl, sodass der erste Befehl in der aktuellen Shell ausgeführt wird.
# File: foo.sh
# We have a work function that may define variables and produce some
# complex output.
work()
{
a=foo
ps -ef
}
# This function uses the work function.
f()
{
# We want to filter the complex output produced by work function but
# at the same time we want that any variables defined by work
# function is available in this function.
work | head -n 2
# Since pipeline launches subshells, the variable defined by work
# function is no longer available in this function.
echo a: $a
}
f
Hier ist der Ausgang.
$ sh foo.sh
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Jul15 ? 00:00:03 /sbin/init
a:
Da das Rohr schafft eine Subshell der die Variablen definiert in work()
bedeutet, gehen verloren, wenn wir zu f()
zurückgegeben, ich das Problem auf diese Weise fixiert.
# File: bar.sh
# We have a work function that may define variables and produce some
# complex output.
work()
{
a=foo
ps -ef
}
# This function uses the work function.
f()
{
# We want to filter the complex output produced by work function but
# at the same time we want that any variables defined by work
# function is available in this function.
work > out.txt
head -n 2 out.txt
echo a: $a
}
f
Hier ist der Ausgang.
$ sh bar.sh
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Jul15 ? 00:00:03 /sbin/init
a: foo
Obwohl das zweite Skript für dieses Spielzeug Beispiel gut funktioniert, kann es (wenn auch lösbare Probleme) zu Problemen führen, wenn f()
mich in einem Rekursion Aufruf endet, die zu out.txt
führen würden durch die gerufene-f überschrieben werden () wenn der Aufrufer-f() sich immer noch darauf verlassen würde. Natürlich kann dies gelöst werden, indem ausreichend auf die Verwendung von out.txt
geachtet wird, d. H. Verwendung von out.txt
nur bevor f() sich selbst aufruft und die Verwendung von out.txt
unter dem Aufruf vermeidet.
Dies hat mich gefragt, ob es eine Möglichkeit gibt, dieses Problem zu lösen, ohne auf eine temporäre Datei zu erstellen. Gibt es eine Möglichkeit, die Ausgabe von work
an einen anderen Befehl zu übergeben, ohne auf Datei-I/O zurückgreifen zu müssen, so dass work
in der aktuellen Shell ausgeführt wird? Ich suche nach Lösungen, die auf jeder POSIX-Shell ausgeführt werden können.
Es gibt eine ** schrecklich **, aber einfach [und tragbar ] Möglichkeit, es zu tun, wenn 'work' zweimal ausgeführt wird, ist kein Problem für Sie (und vorausgesetzt, der zweite Aufruf von 'work' verhält sich genau so wie der erste Aufruf): 'work> &/dev/null && work | head -n 2' – pah
POSIX-Shell-Funktionen verwenden standardmäßig * globale * Variablen, also diese 'unset bar; foo() {bar = baz; }; oof() {foo; echo $ bar; }; oof', gibt zurück: 'baz'. Um den Standardwert zu ändern, verwenden Sie 'local', wie folgt:' unset bar; foo() {lokaler Balken = baz; }; oof() {foo; echo $ bar; }; oof', die nichts zurückgibt. Angesichts dessen sieht es so aus, als ob dieses Q shell * functions * mit shell * scripts * verwechselt hätte. Shell-Skripts werden normalerweise in einer Subshell ausgeführt und können ihre elterliche Umgebung nicht ändern. – agc
@agc Ich verstehe nicht, wie Ihr Kommentar für meine Frage relevant ist. Wie ist 'local' hier überhaupt relevant? Ich möchte die Variablendefinitionen nicht verlieren.Ich möchte, dass die Variablendefinitionen intakt bleiben *. Außerdem ist "local" nicht garantiert in einer POSIX-konformen Shell verfügbar. Das Schlüsselwort 'local' wird nicht von POSIX angegeben. Zum Beispiel unterstützt 'yash' das Schlüsselwort' local' nicht. Ich glaube, Sie haben meine Frage völlig falsch verstanden. –