É 'var = value builtin' igual a 'var = value; construídas em'?

1

Em minha resposta aqui , usei o constructo:

n=$1 shift

Ao ler as especificações do Token Recognition , entendo que o shell analisará essa linha duas partes - a atribuição da variável n=$1 e o comando incorporado shift .

Mas os comentários na minha resposta afirmam que n=$1 shift falha em algumas conchas.

Eu criei uma verificação rápida:

$ for shell in /bin/*[^c]sh; do
  printf '=%-17s=\n' "$shell"
  "$shell" -c 'a=$1 shift; echo "$a"' "$shell" 1
done
=/bin/ash         =
1
=/bin/bash        =

=/bin/dash        =
1
=/bin/heirloom-sh =
1
=/bin/ksh         =
1
=/bin/lksh        =
1
=/bin/mksh        =
1
=/bin/pdksh       =
1
=/bin/posh        =
1
=/bin/schily-osh  =
1
=/bin/schily-sh   =
1
=/bin/yash        =
1
=/bin/zsh         =

Todos os shells, exceto bash e zsh , funcionaram. Mas bash in posix mode e zsh in sh emulation também funcionam:

$ ARGV0=sh bash -c 'a=$1 shift; echo "$a"' sh 1
1
$ ARGV0=sh zsh -c 'a=$1 shift; echo "$a"' sh 1 
1

Usando var=value; shift trabalhado em todos os shells.

Então, essas construções são as mesmas em shells compatíveis com POSIX?

    
por cuonglm 06.03.2016 / 20:01

1 resposta

3

No Bourne Shell, as atribuições de variáveis antes de qualquer tipo de comando interno afetam todo o shell.

Como David Korn começou a criar um Bourne Shell aprimorado com muitos recursos internos antes de adicionar a edição do histórico, pode ter sido óbvio para ele que esse comportamento é um problema.

Como resultado, o ksh88 se comporta de maneira diferente e esse comportamento tornou-se o mestre dos novos padrões POSIX.

A regra atual é:

  • VAR=value antes de um special builtin afetar todo o shell

  • VAR=value antes de qualquer outro comando afetar apenas este comando, mesmo se for um comando interno.

Seu erro foi executar seus testes com um special builtin .

Se você deseja obter uma lista de especialidades especiais, você pode, por exemplo, chame builtin -s no Schily Bourne Shell .

Se você fez seus testes com um conteúdo diferente, por exemplo, com o comando cd , você teria visto resultados diferentes, já que a atribuição da variável só sobreviveria ao comando cd se o teste fosse executado em um Bourne Shell clássico.

Observe, no entanto, que POSIX permite, mas não requer, que um shell mantenha o ambiente com special builtins . Se você gosta de obter o mesmo comportamento para todos os builtins (mesmo builtins especiais), você pode prefixar o nome do builtin por command .

    
por 06.03.2016 / 23:00

Tags