Sim, o comportamento é diferente. Toda a descrição não é tão simples.
Primeiro: quando é igual?
Esta linha de código:
$ var=1; printf "%s" "$var"; var=2 export var; echo " $var"
Será impressa 1 2
em todos os shells (não semelhantes a csh) exceto zsh.
jsh : 1 2 # ATT version sh (heirloom).
ash : 1 2
yash : 1 2
dash : 1 2
zsh/sh : 1 2
bash : 1 2
posixbash : 1 2
lksh : 1 2
mksh : 1 2
ksh93 : 1 2
attsh : 1 2
zsh : 1 1
Isso parece um erro de zsh para mim. Como poderia ser razoável que a exportação de uma variável não retenha o valor exportado?
Mas isso ocorre porque a variável exportada: var
, é a mesma var que é impressa.
Exportando algumas outras variantes
Se a linha for alterada para algo mais parecido com o que você está perguntando, com algum outro nome de variável, como este:
$ var=1; printf "%s" "$var"; var=2 export othervar; echo " $var"
A diferença (s) fica clara:
jsh : 1 2
dash : 1 2
bash : 1 1
posixbash : 1 2
ksh93 : 1 2
zsh : 1 1
É claro que o bash é diferente do sh antigo (Bourne), sh mais recente (traço), ksh e outros (não listados aqui).
Mas o mais importante é que o bash age de maneira diferente de bash --posix
.
Requisito de Posix.
Alguns dos builtins do shell (não todos) são chamados de "built-ins especiais":
De: 2.14. Utilitários Internos Especiais
The following "special built-in" utilities shall be supported in the shell command language.
… however, the special built-in utilities described here differ from regular built-in utilities in two respects:
An error in a special built-in utility may cause a shell executing that utility to abort, while an error in a regular built-in utility shall not cause a shell executing that utility to abort. …
As described in Simple Commands, variable assignments preceding the invocation of a special built-in utility remain in effect after the built-in completes; this shall not be the case with a regular built-in or other utility.
Portanto, em um comando simples: var=2 specialBuiltin
, a variável var
deve reter seu valor após a saída do specialBuiltin. Mas nem todas as implementações de shell seguem essa regra.
Portanto, isso deve imprimir 1 hello 2
(como eval
é um especial incorporado):
var=1; printf '%s ' "$var"; var=2 eval printf %s hello; echo " $var"
Faz em sh
e bash --posix
, mas não em bash simples.
Lista de builtins especiais.
Na verdade, a lista POSIX de especiais especiais está aqui , sendo a lista:
02 break
03 :
04 .
05 continue
06 eval
07 exec
08 exit
09 export
10 readonly
11 return
12 set
13 shift
14 times
15 trap
16 unset
O número na primeira coluna é o valor de var usado para cada teste.
Poderíamos testar todos os builtins especiais (exceto exit, exec e times) com este código:
var=01;
while : ; do var=02 break; done; printf ' %s' "02-$var"; var=01
var=03 : ; printf ' %s' "03-$var"; var=01
echo 'printf " %s" "04-<$var>"' >source-sh
var=04 . source-sh; printf ' %s' "04-$var"; var=01
c=0; while ((c++<1)); do
var=05 continue
done; printf ' %s' "05-$var"; var=01
var=06 eval 'printf " %s" "06-<$var>"'; printf ' %s' "06-$var"; var=01
#( var=07 exec bash -c 'printf " %s" "07-$var"'); var=01
#( var=08 exit; printf ' %s' "08-$var" ); var=01
var=09 export var; printf ' %s' "09-$var"; var=01
var=10 readonly i; printf ' %s' "10-$var"; var=01
varfun(){ var=11 return; }; varfun; printf ' %s' "11-$var"; var=01
var=12 set -- aa ; printf ' %s' "12-$var"; var=01
var=13 shift; printf ' %s' "13-$var"; var=01
var=15 trap; printf ' %s' "14-$var"; var=01
var=16 unset j; printf ' %s' "15-$var"; var=01
echo
Para imprimir esta lista:
jsh : 02-02 03-03 04-<04> 04-04 05-05 06-<06> 06-06 09-09 10-10 11-11 12-12 13-13 15-15 16-16
dash : 02-02 03-03 04-<04> 04-04 05-05 06-<06> 06-06 09-09 10-10 11-11 12-12 13-13 15-15 16-16
bash : 02-01 03-01 04-<04> 04-01 05-01 06-<06> 06-01 09-09 10-01 11-01 12-01 13-01 15-01 16-01
posixbash : 02-02 03-03 04-<04> 04-04 05-05 06-<06> 06-06 09-09 10-10 11-11 12-12 13-13 15-15 16-16
ksh93 : 02-02 03-03 04-<04> 04-04 05-05 06-<06> 06-06 09-09 10-10 11-11 12-12 13-13 15-15 16-16
zsh : 02-01 03-01 04-<04> 04-01 05-01 06-<06> 06-01 09-01 10-01 11-01 12-01 13-01 15-01 16-01
Como você pode ver, onde posix solicita que var retenha 02
a maioria dos shells a retenha e imprima 02-02
, mas não no bash (nem zsh), pois eles imprimem 02-01
. Apenas em export
é impressão bash 09-09
e zsh printing 09-01
.