W niektórych powłokach (w tym bash
):
IFS=: command eval 'p=($PATH)'
(za pomocą bash
można pominąć command
emulację sh / POSIX). Ale uważaj, że gdy używasz zmiennych niecytowanych, to również na ogół musisz set -f
, i nie ma takiego zasięgu lokalnego w większości powłok.
Zsh możesz zrobić:
(){ local IFS=:; p=($=PATH); }
$=PATH
wymusza dzielenie słów, które nie jest domyślnie wykonywane w zsh
(globowanie przy rozszerzaniu zmiennych również nie jest wykonywane, więc nie potrzebujesz, set -f
chyba że w emulacji).
(){...}
(lub function {...}
) są nazywane funkcjami anonimowymi i zwykle są używane do ustawiania zasięgu lokalnego. z innymi powłokami, które obsługują lokalny zasięg funkcji, możesz zrobić coś podobnego z:
e() { eval "$@"; }
e 'local IFS=:; p=($PATH)'
Aby zaimplementować zasięg lokalny dla zmiennych i opcji w powłokach POSIX, możesz także użyć funkcji podanych na stronie https://github.com/stephane-chazelas/misc-scripts/blob/master/locvar.sh . Następnie możesz użyć go jako:
. /path/to/locvar.sh
var=3,2,2
call eval 'locvar IFS; locopt -f; IFS=,; set -- $var; a=$1 b=$2 c=$3'
(nawiasem mówiąc, niepoprawne jest dzielenie w $PATH
ten sposób powyżej, z wyjątkiem tego, zsh
że w innych powłokach IFS jest separatorem pól, a nie separatorem pól).
IFS=$'\n' a=($str)
To tylko dwa zadania, jedno po drugim, tak jak a=1 b=2
.
Uwaga na temat var=value cmd
:
W:
var=value cmd arg
Powłoka wykonuje się /path/to/cmd
w nowym procesie i przechodzi do cmd
oraz arg
do argv[]
i var=value
do envp[]
. To nie jest tak naprawdę przypisanie zmiennych, ale więcej przekazywania zmiennych środowiskowych do wykonywanego polecenia. W powłoce Bourne'a lub Korna set -k
możesz nawet napisać cmd var=value arg
.
Teraz nie dotyczy to wbudowanych funkcji lub funkcji, które nie są wykonywane . W Bourne shell, w var=value some-builtin
, var
kończy się ustawiony jest potem, podobnie jak w var=value
spokoju. Oznacza to na przykład, że zachowanie var=value echo foo
(które nie jest przydatne) różni się w zależności od tego, czy echo
jest wbudowane, czy nie.
POSIX i / lub ksh
zmieniło to, że zachowanie Bourne'a występuje tylko dla kategorii wbudowań zwanych wbudowanymi specjalnymi . eval
jest specjalnym wbudowanym, read
nie jest. W przypadku niespecjalnego wbudowanego, var=value builtin
zestawy var
tylko do wykonania wbudowanego, dzięki czemu zachowuje się podobnie jak podczas wykonywania zewnętrznego polecenia.
command
Komenda może być używany do usuwania szczególną cechę tych szczególnych poleceń wbudowanych . POSIX przeoczył jednak to, że dla wbudowanych eval
i .
, oznaczałoby to, że powłoki musiałyby implementować stos zmiennych (nawet jeśli nie określa poleceń ograniczających zakres local
lub typeset
zakres), ponieważ można wykonać:
a=0; a=1 command eval 'a=2 command eval echo \$a; echo $a'; echo $a
Lub nawet:
a=1 command eval myfunction
z myfunction
funkcją używającą lub ustawiającą $a
i potencjalnie wywołującą command eval
.
To było naprawdę przeoczenie, ponieważ ksh
(na której opiera się głównie specyfikacja) nie wdrożyło go (i AT&T ksh
i zsh
nadal tego nie robi), ale obecnie, z wyjątkiem tych dwóch, większość powłok go implementuje. Zachowanie różni się w zależności od muszli, chociaż może wyglądać tak:
a=0; a=1 command eval a=2; echo "$a"
chociaż. Używanie local
w powłokach, które obsługują, jest bardziej niezawodnym sposobem na wdrożenie zasięgu lokalnego.
IFS=: command eval …
ustawiaIFS
tylko na czas określonyeval
przez POSIX w dash, pdksh i bash, ale nie w ksh 93u. To niezwykłe, że ksh jest dziwnie niezgodny.