In einigen Shells (einschließlich bash
):
IFS=: command eval 'p=($PATH)'
(mit bash
können Sie die command
if 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 -f
ist und in den meisten Shells kein lokaler Bereich dafür vorhanden ist.
Mit zsh können Sie Folgendes tun:
(){ local IFS=:; p=($=PATH); }
$=PATH
ist 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 -f
es 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, zsh
wie 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/cmd
in einem neuen Prozess ausgeführt und passiert cmd
und arg
in argv[]
und var=value
in envp[]
. Das ist nicht wirklich eine Variablenzuweisung, sondern die Übergabe von Umgebungsvariablen an den ausgeführten Befehl. In der Bourne- oder Korn-Shell set -k
kö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
, var
endet danach eingestellt wird, genau wie bei var=value
allein. Das bedeutet zum Beispiel, dass das Verhalten von var=value echo foo
(was nicht nützlich ist) abhängig davon variiert, ob echo
es eingebaut ist oder nicht.
POSIX und / oder hat dies ksh
dahingehend geändert, dass das Bourne-Verhalten nur für eine Kategorie von Buildins auftritt, die als spezielle Buildins bezeichnet werden . eval
ist ein spezielles eingebautes, read
nicht. Für nicht spezielle builtin, var=value builtin
setzt var
nur für die Ausführung des builtin , die es ähnlich wie wenn ein externer Befehl verhalten macht , ist gestartet wird.
Der command
Befehl kann verwendet werden, um das spezielle Attribut dieser speziellen eingebauten Elemente zu entfernen . Was POSIX jedoch übersehen hat, ist, dass für die eval
und .
Builtins die Shells einen Variablenstapel implementieren müssten (obwohl sie die local
oder typeset
bereichsbeschrä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 myfunction
einer Funktion, die verwendet oder einstellt $a
und 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 ksh
und zsh
immer 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 local
von Shells, die dies unterstützen, ist eine zuverlässigere Möglichkeit, den lokalen Bereich zu implementieren.
IFS=: command eval …
setztIFS
nur 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.