He leído lo siguiente en esta pregunta :
bash admite un conmutador --posix, lo que lo hace más compatible con POSIX. También intenta imitar POSIX si se invoca como sh .
La cita anterior supone que /bin/sh
es un enlace al que apunta /bin/bash
.
Pero no entiendo muy bien qué se entiende por "invocado como sh" .
Digamos que tengo el siguiente script que se llama "script.sh":
#!/bin/bash
echo "Hello World"
Por favor, dígame en cada uno de los siguientes casos si el script se ejecutará en bash
modo normal o en modo POSIX (suponga que he ejecutado los siguientes comandos en un terminal que se está ejecutando bash
):
sh script.sh
bash script.sh
./script.sh
Ahora diga que tengo el siguiente script que se llama "script.sh" (que es como el script anterior pero sin shebang):
echo "Hello World"
Por favor, dígame en cada uno de los siguientes casos si el script se ejecutará en bash
modo normal o en modo POSIX (suponga que he ejecutado los siguientes comandos en un terminal que se está ejecutando bash
):
sh script2.sh
bash script2.sh
./script2.sh
Respuestas:
Solo los casos 1 y 4 se ejecutarán en modo POSIX (suponiendo que
sh
sea bash y no alguna otra implementación de sh). Cualquier caso que llame explícitamentebash
sin lo--posix
hará, ya sea desde el shebang o no. Cualquier caso que llame explícitamente losh
hará. El shebang solo se usa cuando ya no se inició explícitamente el shell para el script.El caso 6, si su terminal se está ejecutando
bash
, no se ejecutará en modo POSIX y Bash lo invocará usándose a sí mismo. Si el terminal se ejecuta zsh lugar, el caso 6 podría también funcionar en modo POSIX. POSIX es ambiguo sobre exactamente lo que debería suceder en ese caso , y Bash y zsh tomaron diferentes decisiones allí. Bash invoca el script usándose, mientras que zsh usash
(lo que sea que sea). Otras conchas también varían en ese punto.Una manera simple de saber en qué modo estás es hacer que tu cuerpo de script:
que fallará con un error en el modo POSIX , pero dará instrucciones de uso
kill
fuera de él. Esta es una distinción fácil y funciona a través de una amplia gama de versiones de Bash que se remontan a lo más probable.fuente
bash
a ejecutarse en modo POSIX, como laPOSIXLY_CORRECT
variable de entorno oSHELLOPTS=posix
.[ -o posix ]
es una forma más obvia de verificar que se está ejecutando en modo posix en bash (no en otros shells (excepto yash), por lo que no querrá hacerlo en unsh
script).POSIXLY_CORRECT=1 bash -c '[ -o posix ] && echo yes'
salidasyes
`El "se invoca como" se refiere a lo que sea que el proceso a partir del golpe pone en su argumento de línea de comandos "cero",
argv[0]
.Cuando se inicia un programa con las
exec*()
llamadas al sistema , en realidad no conocen el nombre del archivo binario que contiene el programa, sino que el proceso de llamada es libre de poner lo que quiera allí. Por lo general, por supuesto, el nombre se toma del sistema de archivos, por lo que si ejecuta/bin/sh
, eso es lo que se pone allí. Y si/bin/sh
es Bash, no tiene que ser un enlace simbólico, podría ser un enlace duro o simplemente otra copia del programa de shell.Como ejemplo de configuración del "nombre del programa", el
exec
comando de Bash puede establecer el argumento cero con la-a
opción. (Podríamos hacer lo mismo con Perl, o directamente con C, etc.)Aquí
myname
hay un simple programa en C que simplemente imprime su argumento cero, el nombre que se ve a sí mismo:Fuente:
Pero, para responder las preguntas numeradas ...
(1 y 4) la ejecución
sh somescript
ejecutará losh
que sea que esté en suPATH
, probablemente,/bin/sh
pero posiblemente algo así/usr/xpg4/bin/sh
.sh
.sh
, pero se ejecuta en modo "compatible con SH", que tiene como objetivo ser compatible con el shell Bourne y es sutilmente diferente al modo conforme a POSIX completo en ambos. .(2 y 5) La ejecución
bash somescript
se ejecutará en el modo Bash normal (de nuevo, por supuesto, depende de lo que hayabash
en suPATH
).(3) Aquí, el nombre del script se da directamente a la llamada del sistema en lugar del archivo del programa. El núcleo lee la línea hashbang y la usa para ejecutar el script.
(6) Este es el complejo. Es similar a (3), pero la llamada al sistema para iniciar el programa falla (
ENOEXEC (Exec format error)
), ya que no hay una línea hashbang. Lo que sucede después depende de si la cáscara de la que se está ejecutando es en sí en modo POSIX. POSIX requiere que un shell compatible con POSIX se comporte de manera específica en respuesta aENOEXEC
. Sin embargo, hay cierto margen de maniobra en "un comando equivalente a tener un shell invocado", lo que significa que diferentes shells hacen cosas diferentes./bin/sh
con el nombre del script insertado antes de los otros argumentos como su primer argumento de línea de comandos. El shell Z, el shell Almquist y el shell Korn están (intentando) invocar un shell compatible con POSIX a fuerza de suponer que el/bin/sh
programa es uno.fuente
int main(int argc, char *argv[]){printf("I am %s\n",argv[0]);}
La cáscara es ejecutado ya sea por una llamada en la línea de comandos o el que está en el tinglado (si la línea de comandos no lo especifica).
Por lo tanto, las versiones 1 y 4 se ejecutarán con
sh
, 2 y 5 con bash y 6 pueden no ejecutarse si está utilizando sh (y algunos otros) de forma interactiva. Bash inicia el guión. Ksh también. Zsh comienza como sh.Solo aquellos iniciados como
sh
usarán la opción posix si bash está vinculado/bin/sh
.Agregue esta línea a su script para detectar si alguna versión de bash ksh o zsh la está ejecutando:
fuente