Schrittweite eine Globale variable in der Bash
Hier ist ein shell-Skript:
globvar=0
function myfunc {
let globvar=globvar+1
echo "myfunc: $globvar"
}
myfunc
echo "something" | myfunc
echo "Global: $globvar"
Wenn angerufen wird, druckt das folgende:
$ sh zzz.sh
myfunc: 1
myfunc: 2
Global: 1
$ bash zzz.sh
myfunc: 1
myfunc: 2
Global: 1
$ zsh zzz.sh
myfunc: 1
myfunc: 2
Global: 2
Die Frage ist: warum dies geschieht, und welches Verhalten ist richtig?
P. S. habe ich ein komisches Gefühl, dass die Funktion hinter dem Rohr in einer Gabel-Schale... Also, kann es da einen einfachen workaround?
P. P. S. Diese Funktion ist ein einfacher test wrapper. Es läuft die test-Anwendung, und analysiert die Ausgabe. Dann Schritten von $ÜBERGEBEN oder $FEHLGESCHLAGEN Variablen. Schließlich, Sie erhalten eine Anzahl der bestandenen/fehlerhaften tests, die in der globalen Variablen. Die Nutzung ist wie:
test-util << EOF | myfunc
input for test #1
EOF
test-util << EOF | myfunc
input for test #2
EOF
echo "Passed: $PASSED, failed: $FAILED"
- Haben Sie gelesen: tldp.org/LDP/abs/html/localvar.html ?
- naja, meiner Meinung nach $globvar ist nicht eine lokale variable, weil der Aufruf von myfunc() ohne pipe inkrementiert die Globale variable $globvar ziemlich gut. Das problem ist, dass die aufrufende Funktion über Rohr nicht funktioniert in bash/sh.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Korn-shell gibt die gleichen Ergebnisse wie zsh, durch die Art und Weise.
Finden Sie BashFAQ/024. Rohre erstellen Unterschalen in Bash und Variablen sind verloren, wenn Unterschalen beenden.
Basierend auf deinem Beispiel, würde ich umstrukturieren es so etwas wie dieses:
myfunc() { echo "two words"; }; read word1 word2 <<< $(myfunc)
oderarray=($(myfunc))
.Rohrleitungen etwas in
myfunc
imsh
oderbash
bewirkt, dass eine neue shell zu spawnen. Sie können dies bestätigen, indem Sie hinzufügen einen langen Schlaf inmyfunc
. Während es schlafen nennen -, ps-und Sie werden sehen, einen Teilprozess. Wenn die Funktion zurückgibt, die sub-shell beendet wird, ohne änderung der Wert in den übergeordneten Prozess.Wenn Sie wirklich brauchen, dass der Wert geändert werden, müssen Sie einen Wert zurückgeben von der Funktion und check $PIPESTATUS nach, ich denke, wie diese:
PIPESTATUS
vor.Das problem ist 'das Ende einer pipeline mit eingebautem-ins ausgeführt wird, indem der ursprüngliche Prozess?'
In zsh, es sieht aus wie der Letzte Befehl in der pipeline ausgeführt wird, indem die wichtigsten shell-Skript, wenn der Befehl eine Funktion oder eine built-in.
In der Bash (und Kh ist wahrscheinlich ein link auf die Bash, wenn Sie auf Linux), dann die beiden Befehle ausführen, die in einer sub-shell oder der erste Befehl wird ausgeführt, indem die wichtigsten Prozess-und die anderen werden von sub-shells.
Klar, wenn die Funktion ausgeführt wird in einer sub-shell, es hat keinen Einfluss auf die variable in der übergeordneten shell - (nur die global in der sub-shell).
Sollten Sie erwägen, ein extra-test:
Verwenden
export
stattlet
, andernfalls wird die variable ist lokal(verwenden Sie $(()) als gut zu tun arithmetische operation)