Como posso testar a conformidade POSIX de scripts de shell?

72

Considerando que o POSIX é a coisa mais próxima de um padrão comum entre todos os departamentos, estou interessado em saber se existe um shell que o suporte exclusivamente. Embora a maioria dos shells modernos forneça suporte para POSIX (e executará scripts compatíveis com POSIX sem nenhum problema), eles não fazem um bom trabalho ao apontar recursos não compatíveis.

Existe algum shell que implemente apenas o POSIX e o POSIX, de forma a gerar um erro para qualquer recurso não compatível?

Edição Quero esclarecer que não estou pedindo dicas gerais para escrever scripts de shell portáteis. A questão relacionada mencionada nos comentários já cobriu isso. Pensei nessa questão quando descobri que bashhá uma --posixopção, mas apenas para descobrir que ela afeta apenas alguns comportamentos de inicialização que não são exatamente o que estou procurando.

rahmu
fonte
4
Relacionado: Recursos para programação portátil de shell
Gilles 'SO- stop be evil'
@ Gilles: Talvez eu deva mencionar que me deparei com essa pergunta, mas apenas uma resposta sugeriu o teste dash. Mencionei a portabilidade como um contexto geral para a minha pergunta, mas essa não era sua verdadeira intenção.
rahmu
Claro, eu queria que as duas perguntas fossem vinculadas porque provavelmente são do interesse das mesmas pessoas. Eles não são duplicados por qualquer meio. A propósito, posh é um teste melhor para conformidade com POSIX do que dash.
Gilles 'SO- stop be evil'
2
O busybox está bem próximo apenas do POSIX e POSIX. Uma coisa que pode te atrapalhar é se você também instalar outros pacotes (como diffutils), pois ele poderá adicionar recursos. Saída linux alpinas LiveCD 's que começa-lo com um ambiente busybox puro. O Alpine usa a biblioteca musl C para que você não obtenha extensões GNU que podem adicionar recursos como expressões regulares estendidas.
Michael Fox

Respostas:

37

Infelizmente, 'portátil' é geralmente um requisito mais forte do que 'compatível com POSIX' para scripts de shell. Ou seja, escrever algo que é executado em qualquer shell POSIX não é muito difícil, mas fazê-lo funcionar em qualquer shell do mundo real é mais difícil.

Você pode começar instalando todos os shell no seu gerenciador de pacotes, em particular os poshsons do debian como o que você deseja ( Shell Comum compatível com a Política). A política do Debian é POSIX, com algumas exceções ( echo -nespecificadas, local...).

Além disso, os testes devem abranger alguns shells (especialmente o / bin / sh) em várias plataformas. Eu testei no Solaris (/ bin / sh e xpg4 / sh) e BSD. O AIX e o HP-UX são muito compatíveis e não causam problemas. bash é um pequeno mundo próprio.

Eu recomendo o guia Autoconf para shell portátil , que é absolutamente brilhante e economiza muito tempo. Grandes pedaços são obsoletos, mas tudo bem; apenas pule TruUnix e Ultrix e assim por diante, se você não se importa!

Nicholas Wilson
fonte
poshrealmente soa como o que estou pedindo. Vou fazer alguns testes assim que puder.
rahmu
11
Eu respondi antes de identificar a pergunta relacionada! posh é uma coisa do debian, portanto não será empacotado em todos os sistemas. Além disso, a concha não é necessariamente a coisa com que mais se preocupa; incompatibilidades causadas por problemas são um grande problema, por exemplo.
Nicholas Wilson
Eu não me incomodaria em portar para o Solaris / bin / sh, também conhecido como shell Bourne (que não é POSIX). Solaris como todos unices modernos tem um shell POSIX, ele só acontece de não estar no local habitual (/ usr / XPG4 / bin / sh)
Stéphane Chazelas
Infelizmente, enviamos scripts que precisam ser executados em pelo menos todos os / bin / sh. Não é tão ruim quanto tudo isso ... Eu prefiro não ter que fazer isso.
Nicholas Wilson
2
A razão pela qual trato o / bin / sh como importante é porque ele é chamado a partir do shebang em muitos scripts. "/ usr / bin / env sh" não é uma melhoria. Se você fizer algum esforço para fazer algo funcionar em shells não POSIX, acho que também posso priorizar / bin / sh de cada sistema. Não demorará muito para que algum cliente execute seu script com o shell padrão, o que não é tão irracional.
Nicholas Wilson
28

Você pode usar o ShellCheck (GitHub) como um linter para seus scripts de shell. Existe também uma versão online .

Para detectar problemas de compatibilidade com POSIX (por exemplo, SC2039 ), a linha shebang do seu shell script deve ser #!/bin/sh. Você também pode passar --shell=shpara shellcheck.

Exemplo ( test.sh):

#!/bin/sh
if [[ $HOSTNAME == test ]]; then
    echo fail &> foo
fi

Resultado ( shellcheck test.sh):

In test.sh line 2:
if [[ $HOSTNAME == test ]]; then
   ^-- SC2039: In POSIX sh, [[ ]] is undefined.
      ^-- SC2039: In POSIX sh, HOSTNAME is undefined.    

In test.sh line 3:
    echo fail &> foo
              ^-- SC2039: In POSIX sh, &> is undefined.
johnLate
fonte
11
Todos esses anos e nunca ouvi falar do ShellCheck ... obrigado pelo link!
Ton van den Heuvel
Melhor ferramenta de sempre! Especialmente ter uma versão online dela é incrível para verificar rapidamente um pedaço de código!
Mecki 30/04
12

O Bash será executado no modo compatível com POSIX se a POSIXLY_CORRECTvariável de ambiente estiver definida. Na página de manual:

   POSIXLY_CORRECT
          If  this  variable  is  in the environment when bash starts, the
          shell enters posix mode before reading the startup files, as  if
          the  --posix  invocation option had been supplied.  If it is set
          while the shell is running, bash enables posix mode, as  if  the
          command set -o posix had been executed.

Muitos outros utilitários GNU também serão respeitados POSIXLY_CORRECT, portanto, se você estiver em um sistema com ferramentas predominantemente GNU (por exemplo, a maioria dos sistemas Linux), este será um bom começo se seu objetivo for a conformidade com POSIX.

James Sneeringer
fonte
21
Mesmo no modo POSIX, o bash ainda permite alguns recursos não POSIX, como [[.
Jordanm