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/shes 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 bashmodo normal o en modo POSIX (suponga que he ejecutado los siguientes comandos en un terminal que se está ejecutando bash):
sh script.shbash 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 bashmodo normal o en modo POSIX (suponga que he ejecutado los siguientes comandos en un terminal que se está ejecutando bash):
sh script2.shbash script2.sh./script2.sh

Respuestas:
Solo los casos 1 y 4 se ejecutarán en modo POSIX (suponiendo que
shsea bash y no alguna otra implementación de sh). Cualquier caso que llame explícitamentebashsin lo--posixhará, ya sea desde el shebang o no. Cualquier caso que llame explícitamente loshhará. 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
killfuera 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
basha ejecutarse en modo POSIX, como laPOSIXLY_CORRECTvariable 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 unshscript).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/shes 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
execcomando de Bash puede establecer el argumento cero con la-aopción. (Podríamos hacer lo mismo con Perl, o directamente con C, etc.)Aquí
mynamehay 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 somescriptejecutará loshque sea que esté en suPATH, probablemente,/bin/shpero 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 somescriptse ejecutará en el modo Bash normal (de nuevo, por supuesto, depende de lo que hayabashen 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/shcon 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/shprograma 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
shusará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