Die Grundidee ist , dass die VAR=VALUE some-commandSätze VARauf die VALUEfür die Ausführung von , some-commandwenn some-commandein externer Befehl, und es wird nicht mehr Phantasie als das. Wenn Sie diese Intuition mit etwas Wissen über die Funktionsweise einer Shell kombinieren, sollten Sie in den meisten Fällen die richtige Antwort finden. Die POSIX-Referenz lautet "Einfache Befehle" im Kapitel "Shell Command Language" .
Wenn some-commandes sich um einen externen Befehl handelt , VAR=VALUE some-commandentspricht dies env VAR=VALUE some-command. VARwird in die Umgebung von exportiert some-command, und sein Wert (oder das Fehlen eines Werts) in der Shell ändert sich nicht.
Wenn some-commandes sich um eine Funktion handelt , VAR=VALUE some-commandist dies äquivalent zu VAR=VALUE; some-command, dh die Zuweisung bleibt bestehen, nachdem die Funktion zurückgegeben wurde, und die Variable wird nicht in die Umgebung exportiert. Der Grund dafür hängt mit dem Design der Bourne-Shell (und später mit der Abwärtskompatibilität) zusammen: Sie hatte keine Möglichkeit, Variablenwerte um die Ausführung einer Funktion herum zu speichern und wiederherzustellen. Das Nichtexportieren der Variablen ist sinnvoll, da eine Funktion in der Shell selbst ausgeführt wird. Ksh (einschließlich ATT ksh93 und pdksh / mksh), bash und zsh implementieren jedoch das nützlichere Verhalten, wenn VARes nur während der Ausführung der Funktion festgelegt wird (es wird auch exportiert). In ksh geschieht dies, wenn die Funktion mit der ksh-Syntax definiert istfunction NAME …nicht, wenn es mit der Standardsyntax definiert ist NAME (). In Bash wird dies nur im Bash-Modus durchgeführt, nicht im POSIX-Modus (wenn mit ausgeführt POSIXLY_CORRECT=1). In zsh geschieht dies, wenn die posix_builtinsOption nicht gesetzt ist. Diese Option ist standardmäßig nicht aktiviert, wird jedoch von emulate shoder aktiviert emulate ksh.
Wenn some-commandes sich um eine integrierte Funktion handelt, hängt das Verhalten vom Typ der integrierten Funktion ab. Spezielle Builtins verhalten sich wie Funktionen. Spezielle integrierte Funktionen müssen in der Shell implementiert werden, da sie die Status-Shell beeinflussen (z. B. den breakKontrollfluss cdbeeinflussen, das aktuelle Verzeichnis setbeeinflussen, Positionsparameter und -optionen beeinflussen…). Andere eingebaute Funktionen dienen nur der Leistung und der Benutzerfreundlichkeit (meistens - z. B. kann die Bash-Funktion printf -vnur von einer eingebauten Funktion implementiert werden) und verhalten sich wie externe Befehle.
Die Zuweisung erfolgt nach der Alias-Erweiterung. Wenn some-commandes sich also um einen Alias handelt , erweitern Sie ihn zuerst, um herauszufinden, was passiert.
Beachten Sie, dass die Zuweisung in allen Fällen ausgeführt wird, nachdem die Befehlszeile analysiert wurde, einschließlich der Variablenersetzung in der Befehlszeile. Also var=a; var=b echo $vardruckt a, weil $varausgewertet wird, bevor die Zuordnung erfolgt. Und IFS=. printf "%s\n" $varnutzt somit den alten IFSWert zum Teilen $var.
Ich habe alle Arten von Befehlen behandelt, aber es gibt noch einen weiteren Fall: Wenn kein Befehl ausgeführt werden muss , dh wenn der Befehl nur aus Zuweisungen (und möglicherweise Umleitungen) besteht. In diesem Fall bleibt die Zuordnung bestehen . VAR=VALUE OTHERVAR=OTHERVALUEist äquivalent zu VAR=VALUE; OTHERVAR=OTHERVALUE. So nach IFS=. arr=($var), IFSbleibt auf .. Da Sie $IFSin der Zuordnung zu arrmit der Erwartung verwenden könnten, dass es bereits seinen neuen Wert hat, ist es sinnvoll, dass der neue Wert von IFSfür die Erweiterung von verwendet wird $var.
Zusammenfassend können Sie nur IFSfür die temporäre Feldaufteilung verwenden:
- durch Starten einer neuen Shell oder einer Subshell (z. B.
third=$(IFS=.; set -f; set -- $var; echo "$3")ist eine komplizierte Methode, mit der third=${var#*.*.}Ausnahme, dass sie sich anders verhalten, wenn der Wert von varweniger als zwei .Zeichen enthält);
- in KSH, mit
IFS=. some-functiondenen some-functionmit der KSH Syntax definiert ist function some-function …;
- in bash und zsh,
IFS=. some-functionsolange sie im einheitlichen Modus im Gegensatz zum Kompatibilitätsmodus ausgeführt werden.
IFSbleibt auf." Eek. Nachdem ich den ersten Teil gelesen habe, macht das Sinn, aber bevor ich diesen Fragebogen gepostet habe, hätte ich das nicht erwartet.