Em algumas conchas (incluindo bash):
IFS=: command eval 'p=($PATH)'
(com bash, você pode omitir a commandse não estiver na emulação sh / POSIX). Mas lembre-se de que, ao usar variáveis não citadas, você geralmente também precisa set -f, e não há escopo local para isso na maioria dos shells.
Com o zsh, você pode fazer:
(){ local IFS=:; p=($=PATH); }
$=PATHé forçar a divisão de palavras que não é feita por padrão em zsh(globbing na expansão de variáveis também não é feito, então você não precisa, a set -fmenos que seja em emulação de sh).
(){...}(ou function {...}) são chamadas de funções anônimas e geralmente são usadas para definir um escopo local. com outros shells que oferecem suporte ao escopo local em funções, você pode fazer algo semelhante com:
e() { eval "$@"; }
e 'local IFS=:; p=($PATH)'
Para implementar um escopo local para variáveis e opções nos shells POSIX, você também pode usar as funções fornecidas em https://github.com/stephane-chazelas/misc-scripts/blob/master/locvar.sh . 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 $PATHdessa maneira acima, exceto zshem outros shells, o IFS é delimitador de campo, não separador de campo).
IFS=$'\n' a=($str)
São apenas duas tarefas, uma após a outra a=1 b=2.
Uma nota explicativa sobre var=value cmd:
Em:
var=value cmd arg
Os executa shell /path/to/cmdem um novo processo e passes cmde argem argv[]e var=valueem envp[]. Isso não é realmente uma atribuição de variável, 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 funções internas ou funções que não são executadas . No shell Bourne, em var=value some-builtin, varacaba sendo definido posteriormente, assim como var=valuesozinho. Isso significa, por exemplo, que o comportamento de var=value echo foo(que não é útil) varia dependendo se echoestá embutido ou não.
O POSIX e / ou kshalterou o fato de que o comportamento Bourne ocorre apenas para uma categoria de componentes internos chamados componentes especiais . evalé um builtin especial, readnão é. Para embutidos não especiais, var=value builtindefine varapenas para a execução do embutido, o que o comporta de maneira semelhante a quando um comando externo está sendo executado.
O commandcomando pode ser usado para remover o especial atributo desses builtins especiais . O que o POSIX ignorou é que, para os evale .builtins, isso significaria que os shells precisariam implementar uma pilha variável (mesmo que não especifique os comandos de limitação de escopo localou typeset), porque você poderia fazer:
a=0; a=1 command eval 'a=2 command eval echo \$a; echo $a'; echo $a
Ou até:
a=1 command eval myfunction
com myfunctionsendo uma função usando ou a criação $ae potencialmente chamando command eval.
Isso foi realmente um esquecimento, porque ksh(no qual a especificação é baseada principalmente) não a implementou (e a AT&T kshe zshainda não o fez), mas hoje em dia, exceto os dois, a maioria das conchas o implementa. O comportamento varia entre as conchas, embora em coisas como:
a=0; a=1 command eval a=2; echo "$a"
Apesar. O uso localde shells compatíveis é uma maneira mais confiável de implementar o escopo local.
IFS=: command eval …defineIFSapenas a duração doeval, conforme exigido pelo POSIX, no hífen, pdksh e bash, mas não no ksh 93u. É incomum ver o ksh ser o único fora de conformidade.