¿Cómo puedo probar el cumplimiento POSIX de los scripts de shell?


72

Teniendo en cuenta que POSIX es lo más parecido a un estándar común entre todos los unices, me interesa saber si hay un shell que lo soporte exclusivamente. Si bien la mayoría de los shells modernos brindan soporte para POSIX (y ejecutarán scripts compatibles con POSIX sin ningún problema), no hacen un buen trabajo al señalar características no compatibles.

¿Hay algún shell que implemente POSIX y POSIX solamente, de tal manera que arroje un error para cualquier característica no compatible?

EDITAR Quiero aclarar que no estoy pidiendo consejos generales para escribir scripts de shell portátiles. La pregunta relacionada mencionada en los comentarios ya cubrió esto. Pensé en esta pregunta cuando descubrí que bashtiene una --posixopción, pero solo para descubrir que solo afecta algunos comportamientos de inicialización que no es exactamente lo que estoy buscando.



@Gilles: Tal vez debería mencionar que me encontré con esta pregunta, pero solo una respuesta sugirió probar con dash. Mencioné la portabilidad como contexto general para mi pregunta, pero esa no era su verdadera intención.
rahmu

Claro, quería que las dos preguntas estuvieran vinculadas porque es probable que sean de interés para las mismas personas. No son duplicados de ninguna manera. Por cierto, posh es una mejor prueba para el cumplimiento de POSIX que dash.
Gilles 'SO- deja de ser malvado'

2
busybox está bastante cerca de POSIX y POSIX solamente. Una cosa que puede hacer que tropieces es que si también instalas otros paquetes (como diffutils), entonces podría agregar características. Pedido Linux alpinos 's LiveCD que comienza con un entorno busybox puro. Alpine usa la biblioteca musl C para que no obtenga extensiones GNU que puedan agregar características como expresiones regulares extendidas.
Michael Fox

Respuestas:


37

Desafortunadamente, 'portable' suele ser un requisito más estricto que 'compatible con POSIX' para los scripts de shell. Es decir, escribir algo que se ejecute en cualquier shell POSIX no es demasiado difícil, pero hacer que se ejecute en cualquier shell del mundo real es más difícil.

Puede comenzar instalando cada shell en su administrador de paquetes, en particular los poshsonidos de debian como lo que quiere (SHELL Ordinary compatible con las políticas). La política de Debian es POSIX con algunas excepciones ( echo -nespecificadas, local...).

Sin embargo, más allá de eso, las pruebas deben cubrir algunos shells (/ bin / sh especialmente) en una gama de plataformas. Pruebo en Solaris (/ bin / sh y xpg4 / sh) y BSD. AIX y HP-UX son muy compatibles y no causan problemas. bash es un pequeño mundo propio.

Recomiendo la guía Autoconf de shell portátil , que es absolutamente brillante y ahorra mucho tiempo. Grandes partes de ella son obsoletas, pero está bien; ¡solo omita TruUnix y Ultrix y así sucesivamente si no le importa!


poshde hecho suena como lo que estoy pidiendo. Haré algunas pruebas tan pronto como pueda.
rahmu

1
¡Respondí antes de detectar la pregunta relacionada! elegante es una cosa debian, por lo que no se incluirá en todos los sistemas. Además, el caparazón no es necesariamente lo que más le preocupa; Las incompatibilidades sed son un gran problema, por ejemplo.
Nicholas Wilson

No me molestaría en portar a Solaris / bin / sh, también conocido como Bourne Shell (que no es POSIX). Solaris, como todos los dispositivos modernos, tiene un shell POSIX, simplemente no está en la ubicación habitual (/ usr / xpg4 / bin / sh)
Stéphane Chazelas

Lamentablemente, enviamos scripts que deben ejecutarse en al menos cada / bin / sh. No es tan malo como todo eso ... Sin embargo, prefiero no tener que hacerlo.
Nicholas Wilson el

2
La razón por la que trato a / bin / sh como importante es porque se invoca desde shebang en muchos scripts. "/ usr / bin / env sh" no es una mejora. Si va a hacer un esfuerzo para hacer que algo funcione en shells que no sean POSIX, creo que también podría priorizar cada sistema / bin / sh. No pasará mucho tiempo antes de que algún cliente ejecute su script con el shell predeterminado, que no es tan irracional.
Nicholas Wilson el

28

Puede usar ShellCheck (GitHub) como un linter para sus scripts de shell. También hay una versión en línea .

Para detectar problemas de compatibilidad POSIX (por ejemplo, SC2039 ), la línea shebang de su script de shell debería ser #!/bin/sh. También puedes pasar --shell=sha shellcheck.

Ejemplo ( 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.

1
Todos estos años y nunca oí hablar de ShellCheck ... ¡gracias por el enlace!
Ton van den Heuvel

¡La mejor herramienta de todas! ¡Especialmente tener una versión en línea es increíble para verificar rápidamente un código!
Mecki

12

Bash se ejecutará en modo compatible con POSIX si se establece la POSIXLY_CORRECTvariable de entorno. Desde la página del 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.

Muchas otras utilidades de GNU también honrarán POSIXLY_CORRECT, por lo que si está en un sistema con herramientas predominantemente de GNU (por ejemplo, la mayoría de los sistemas Linux), este es un buen comienzo si su objetivo es la conformidad POSIX.


21
Incluso en modo POSIX, bash seguirá permitiendo algunas funciones que no sean POSIX, como [[.
jordanm
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.