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.