¿Qué shell ejecuta scripts cuando no hay una línea shebang (#! / Path / to / shell) al principio? Asumo / bin / sh pero no puedo confirmar.
El núcleo se niega a ejecutar tales secuencias de comandos y devuelve ENOEXEC, por lo que el comportamiento exacto depende del programa que se ejecuta una secuencia de comandos de .
- bash 4.2.39 - se usa a sí mismo
- busybox-ash 1.20.2 - se usa a sí mismo
- guión 0.5.7 - carreras / bin / sh
- pescado 1.23.1 - se queja de ENOEXEC, luego culpa al archivo equivocado
- AT&T ksh 93u + 2012.08.01 - se usa a sí mismo
- mksh R40f - carreras / bin / sh
- pdksh 5.2.14 - carreras / bin / sh
- sh-heirloom 050706 - se usa a sí mismo
- tcsh 6.18.01 - carreras / bin / sh
- zsh 5.0.0 - ejecuta / bin / sh
- cmd.exe 5.1.2600: te mira divertido.
En glibc , funciona execv()
o execve()
simplemente devuelve ENOEXEC. Pero execvp()
oculta este código de error e invoca automáticamente / bin / sh. (Esto está documentado en exec (3p)) .
¿Qué se considera "mejores prácticas" en términos de escribir scripts de shell que se ejecutarán en cualquier plataforma? (ok, esto es algo abierto)
Apéguese a sh
las características definidas por POSIX y solo a ellas, o simplemente vaya a bash completo (que está ampliamente disponible) y menciónelo en sus requisitos si lo distribuye.
(Ahora que lo pienso, Perl, o tal vez Python, sería aún más portátil, sin mencionar que tiene una mejor sintaxis).
Siempre agregue la línea shebang. Si usa bash o zsh, use en #!/usr/bin/env bash
lugar de codificar la ruta del shell. (Sin embargo, se garantiza que el shell POSIX esté en /bin/sh
, así que omita env
en ese caso).
(Desafortunadamente, incluso /bin/sh
no siempre es lo mismo. El programa de autoconfiguración de GNU tiene que lidiar con muchas peculiaridades diferentes ).
¿Es posible escribir un script que intente usar zsh y vuelva a bash si zsh no está disponible? Intenté poner dos líneas shebang, como a continuación, pero solo errores con un mal intérprete: / bin / zsh: no existe tal archivo o directorio si lo intento en una máquina sin zsh.
Solo puede haber una línea shebang; todo después del carácter de nueva línea ni siquiera es leído por el kernel, y tratado por shells.
Es posible escribir un script que se ejecute como #!/bin/sh
, comprueba qué shell está disponible y se ejecuta exec zsh "$0" "$@"
o exec bash "$0" "$@"
depende del resultado. Sin embargo, la sintaxis utilizada por bash y zsh es tan diferente en varios lugares que no recomendaría hacerlo por su propia cordura.
strace -f -e fork,clone,execve
. Algunos proyectiles fueron ejecutados/bin/sh
después del fracaso; otros interpretaron el guión ellos mismos.readlink /proc/$$/exe
.csh
ytcsh
, el comportamiento depende de si el script comienza con#
(en cuyo caso se invocan a sí mismos en lugar de sh para interpretar el script). Eso se remonta a la época en que csh admite comentarios pero no el shell Bourne, por lo que a#
fue una pista de que era un script csh.1) El shell actual en el que se está ejecutando (cualquiera que sea el shell)
2) Quédese con el mismo tipo de shell (bash / dash / ash / csh / sea cual sea su sabor) y asegúrese de que sus "plataformas compatibles" instalen el shell que desea utilizar de forma predeterminada. Además, intente utilizar comandos comúnmente disponibles en los sistemas. Evite las opciones específicas de la máquina.
3) No hay realmente una lógica de "si-entonces-otro" para el
interpreter directive
. Debe especificar un shell que debería existir en todos los sistemas que desea admitir ... es decir,#!/bin/bash
o especificar un genérico#!/bin/sh
siempre que su script sea bastante genérico en todos los shells.fuente