Em alguns shells (incluindo bash ):
IFS=: command eval 'p=($PATH)'
(com bash , você pode omitir o command se não estiver em emulação sh / POSIX). Mas cuidado ao usar variáveis sem aspas, você geralmente também precisa de set -f , e não há escopo local para isso na maioria dos shells.
Com zsh, você pode fazer:
(){ local IFS=:; p=($=PATH); }
$=PATH é forçar a divisão de palavras, o que não é feito por padrão em zsh (a globulação após a expansão de variáveis também não é feita, portanto, você não precisa de set -f a menos que em shulation).
(){...} (ou function {...} ) são chamados de funções anônimas e são normalmente usados para definir um escopo local. com outras shells que suportem escopo local em funções, você poderia fazer algo similar com:
e() { eval "$@"; }
e 'local IFS=:; p=($PATH)'
Para implementar um escopo local para variáveis e opções em shells POSIX, você também pode usar as funções fornecidas em link . Então você pode usá-lo como:
. /path/to/locvar.sh
var=3,2,2
call eval 'locvar IFS; locopt -f; IFS=,; set -- $var; a=$1 b=$2 c=$3'
(a propósito, é inválido dividir $PATH dessa forma acima, exceto em zsh como em outros shells, o IFS é um delimitador de campo, não um separador de campo).
IFS=$'\n' a=($str)
São apenas duas tarefas, uma após a outra, como a=1 b=2 .
Uma nota de explicação sobre var=value cmd :
Em:
var=value cmd arg
O shell executa /path/to/cmd em um novo processo e passa cmd e arg em argv[] e var=value em envp[] . Isso não é realmente uma atribuição de variáveis, mas mais variáveis de ambiente de passagem para o comando executado . No shell Bourne ou Korn, com set -k , você pode até escrever cmd var=value arg .
Agora, isso não se aplica a builtins ou funções que não são executadas . No shell Bourne, em var=value some-builtin , var acaba sendo definido posteriormente, assim como com var=value sozinho. Isso significa, por exemplo, que o comportamento de var=value echo foo (que não é útil) varia dependendo se o echo está embutido ou não.
POSIX e / ou ksh mudaram isso porque o comportamento de Bourne só acontece para uma categoria de builtins chamados special builtins . eval é um especial embutido, read não é. Para construções não especiais, var=value builtin define var apenas para a execução do builtin, o que faz com que ele se comporte de forma semelhante a quando um comando externo está sendo executado.
O comando command pode ser usado para remover o atributo especial dos especiais incorporados . O que POSIX ignorou é que, para os eval e . builtins, isso significaria que shells teriam que implementar uma pilha variável (mesmo que não especifique os comandos% limitlocal ou typeset scope limiting), porque você poderia fazer:
a=0; a=1 command eval 'a=2 command eval echo \$a; echo $a'; echo $a
Ou até mesmo:
a=1 command eval myfunction
com myfunction sendo uma função usando ou configurando $a e possivelmente chamando command eval .
Isso foi realmente uma negligência porque ksh (em que a especificação é baseada principalmente) não o implementou (e AT & T ksh e zsh ainda não o fazem), mas hoje em dia, exceto esses dois , a maioria das shells implementa isso. O comportamento varia entre os shells em coisas como:
a=0; a=1 command eval a=2; echo "$a"
embora. Usar local em shells compatíveis é uma maneira mais confiável de implementar o escopo local.