Existe algum código sh que não seja código bash sintaticamente válido?

31

Existe algum shcódigo que não seja código bash sintaticamente válido (não vomitará na sintaxe)?

Estou pensando em substituir shcom bashpara certos comandos.

Alexander Mills
fonte
11
Eu acho que pelo válida eu quis dizer sintaticamente válido, por isso não vai vomitar na sintaxe
Alexander Mills
2
Tokenização diferente? por exemplo, ((vem à mente.
Ccorn 11/05/19
11
Para algumas distros /usr/bin/shé apenas um link simbólico para /usr/bin/bash(eu estou usando o CentOS 7.3 e é). Você deve verificar se shé realmente basha sua distribuição.
Centimane
11
Alguns anos atrás, todo o meu projeto foi interrompido quando algo foi "atualizado" no bash. Eu tive que mudar todas as minhas linhas de shebang de #!/bin/shpara #!/bin/bash. Então tudo funcionou novamente, então você realmente precisa ter cuidado. Pode ter acontecido quando eles começaram a usar o traço em vez do bash para sh.
1111 Joe
11
@ Joe, isso é o oposto do que o OP está pedindo - você tinha o código do bash que foi rotulado incorretamente como código sh, mas não era. O OP está perguntando se eles podem ter código sh (real, não rotulado incorretamente) que é interrompido quando executado com o bash, não se eles podem ter código bash que é interrompido quando executado com sh (o que é óbvio - se as extensões do bash não qualquer efeito sobre os recursos de idioma disponíveis, eles não seriam extensões).
Charles Duffy

Respostas:

49

Aqui está um código que faz algo diferente no POSIX sh e Bash:

hello &> world

Se isso é "inválido" para você, não sei.

Em Bash, ele redireciona ambos saída padrão e erro padrão a partir hellopara o arquivo world. No POSIX sh, ele é executado helloem segundo plano e, em seguida, faz um redirecionamento vazio para world, truncando-o (ou seja, é tratado como & >).

Existem muitos outros casos em que as extensões Bash funcionam quando executadas em baixo bashe têm efeitos diferentes em um POSIX puro sh. Por exemplo, a expansão de chaves é outra, e também opera da mesma forma no modo POSIX do Bash e não.


No que diz respeito aos erros estáticos de sintaxe, o Bash possui as duas palavras reservadas (como [[e time) não especificadas pelo POSIX, como [[ xum código de shell POSIX válido, mas um erro de sintaxe do Bash e um histórico de vários erros de incompatibilidade do POSIX que podem resultar em erros de sintaxe, como o desta pergunta :

x=$(cat <<'EOF'
`
EOF
)
bash: line 2: unexpected EOF while looking for matching ``'
bash: line 5: syntax error: unexpected end of file

Somente erros de sintaxe é uma definição bastante perigosa de "inválido" para qualquer circunstância em que isso importe, mas aí está.

Michael Homer
fonte
3
Observe que, embora a expansão entre chaves atualmente torne o bash (e zsh, pdksh, ksh93) não compatível, o POSIX está trabalhando para adicionar provisões na especificação para permitir a expansão entre chaves (e {fd}>fileum problema semelhante), para que o bash possa ser novamente compatível (expansão entre chaves) permaneceria não especificado, mas os scripts compatíveis precisariam ser executados caso echo "{a,b}"desejem {a,b}ser gerados). Veja a discussão que começou
Stéphane Chazelas
2
Também relevante para estas perguntas e respostas: austingroupbugs.net/view.php?id=1191#c3983
Stéphane Chazelas
2
Alguém escrevendo um script no POSIX alguma vez escreveria um comando como este? O OP está indo de sh para bash e, pelo que entendi, parece que seria mais um problema indo na outra direção?
Rich
11
@ Rich: Claro. Eu não uso nenhum sistema onde /bin/shestá o bash, então, se eu não estivesse ciente desse basismo, escrever uma linha de comando poderia acontecer facilmente. O espaçamento na resposta faz com que pareça improvável, mas hello&>worldé menos abrangente.
R ..
2
Na verdade, vi um bug devido à &>diferença no mês passado!
Gordon Davisson
16

Um pequeno exemplo:

time()(:)

timeno Bash é uma palavra reservada e se comporta de maneira diferente do timeprograma. É bem provável que você quebre alguns scripts práticos tentando analisar o resultado timeusando o bash. Mas tecnicamente não é um erro de sintaxe. Redefinir timecomo uma função seria raro, mas causa um erro de sintaxe, conforme esta pergunta especifica.

Um exemplo mais curto:

a():

Válido dash, mas não compatível com POSIX.

user23013
fonte
3
De maneira mais geral, qualquer palavra que seja uma palavra-chave não padrão ou um comando interno no Bash causará o mesmo efeito. Além de time, há coisas como declare, function, select, e coproc. Embora alguns deles estejam explicitamente marcados como não especificados no padrão ( palavras - chave e componentes internos / utilitários ), mas não consigo ver, por exemplo, timeou coprocna lista. E o uso --posixnão parece ajudar.
Ilkkachu 11/0518