In einigen Shells (einschließlich bash):
IFS=: command eval 'p=($PATH)'
(mit bashkönnen Sie die commandif not in sh / POSIX-Emulation weglassen ). Beachten Sie jedoch, dass bei der Verwendung von Variablen ohne Anführungszeichen in der Regel auch dies erforderlich set -fist und in den meisten Shells kein lokaler Bereich dafür vorhanden ist.
Mit zsh können Sie Folgendes tun:
(){ local IFS=:; p=($=PATH); }
$=PATHist zu Wort Spaltung zu zwingen , die nicht standardmäßig in getan wird zsh(Globbing auf variable Expansion erfolgt auch nicht , so dass Sie nicht brauchen , set -fes sei denn in sh - Emulation).
(){...}(oder function {...}) werden als anonyme Funktionen bezeichnet und in der Regel zum Festlegen eines lokalen Bereichs verwendet. Mit anderen Shells, die den lokalen Funktionsumfang unterstützen, können Sie Folgendes tun:
e() { eval "$@"; }
e 'local IFS=:; p=($PATH)'
Um einen lokalen Bereich für Variablen und Optionen in POSIX-Shells zu implementieren, können Sie auch die unter https://github.com/stephane-chazelas/misc-scripts/blob/master/locvar.sh bereitgestellten Funktionen verwenden . Dann können Sie es verwenden als:
. /path/to/locvar.sh
var=3,2,2
call eval 'locvar IFS; locopt -f; IFS=,; set -- $var; a=$1 b=$2 c=$3'
(Übrigens ist es ungültig, so zu teilen $PATH, außer in, zshwie in anderen Shells, IFS ist ein Feldtrennzeichen, kein Feldtrennzeichen).
IFS=$'\n' a=($str)
Ist nur zwei Aufgaben, die einer nach dem anderen genau gefallen a=1 b=2.
Eine Erläuterung zu var=value cmd:
Im:
var=value cmd arg
Die Shell wird /path/to/cmdin einem neuen Prozess ausgeführt und passiert cmdund argin argv[]und var=valuein envp[]. Das ist nicht wirklich eine Variablenzuweisung, sondern die Übergabe von Umgebungsvariablen an den ausgeführten Befehl. In der Bourne- oder Korn-Shell set -kkönnen Sie mit sogar schreiben cmd var=value arg.
Dies gilt nicht für integrierte Funktionen oder Funktionen, die nicht ausgeführt werden . In der Bourne - Shell, in var=value some-builtin, varendet danach eingestellt wird, genau wie bei var=valueallein. Das bedeutet zum Beispiel, dass das Verhalten von var=value echo foo(was nicht nützlich ist) abhängig davon variiert, ob echoes eingebaut ist oder nicht.
POSIX und / oder hat dies kshdahingehend geändert, dass das Bourne-Verhalten nur für eine Kategorie von Buildins auftritt, die als spezielle Buildins bezeichnet werden . evalist ein spezielles eingebautes, readnicht. Für nicht spezielle builtin, var=value builtinsetzt varnur für die Ausführung des builtin , die es ähnlich wie wenn ein externer Befehl verhalten macht , ist gestartet wird.
Der commandBefehl kann verwendet werden, um das spezielle Attribut dieser speziellen eingebauten Elemente zu entfernen . Was POSIX jedoch übersehen hat, ist, dass für die evalund .Builtins die Shells einen Variablenstapel implementieren müssten (obwohl sie die localoder typesetbereichsbeschränkenden Befehle nicht angeben ), weil Sie Folgendes tun könnten:
a=0; a=1 command eval 'a=2 command eval echo \$a; echo $a'; echo $a
Oder auch:
a=1 command eval myfunction
mit myfunctioneiner Funktion, die verwendet oder einstellt $aund möglicherweise aufruft command eval.
Das war wirklich ein Versehen, weil ksh(worauf die Spezifikation hauptsächlich basiert) es nicht implementiert hat (und AT & T kshund zshimmer noch nicht), aber heutzutage, mit Ausnahme dieser beiden, implementieren die meisten Shells es. Das Verhalten der Muscheln variiert jedoch in folgenden Punkten:
a=0; a=1 command eval a=2; echo "$a"
obwohl. Die Verwendung localvon Shells, die dies unterstützen, ist eine zuverlässigere Möglichkeit, den lokalen Bereich zu implementieren.
IFS=: command eval …setztIFSnur für die Dauer dereval, wie von POSIX vorgeschrieben, in Bindestrich, Pdksh und Bash, aber nicht in Ksh 93u. Es ist ungewöhnlich, zu sehen, dass ksh die seltsame Ausnahme ist.