los scripts de shell todavía funcionan sin #! (línea sha-bang)

10

Soy nuevo en los scripts de shell y muchos libros han escrito que usan la línea #! (Sha-bang) al inicio del script para invocar al intérprete. Y esto invocará un nuevo shell para el script y hará la interpretación línea por línea. Pero uno de mi script básico todavía se está ejecutando sin la línea mágica.

entonces mis preguntas son:

  • ¿De dónde sacó mi guión básico el intérprete?
  • ¿Cómo logró el guión localizar al intérprete?

ahora déjame contarte sobre mi script básico, solo contiene la siguiente línea:

echo "guión básico sin las líneas mágicas"

usuario1678213
fuente

Respuestas:

3

Si no se proporciona la línea mágica, se utiliza un shell predeterminado para ejecutar el script. Este shell predeterminado podría ser Bourne shell (sh), como es el caso en algunos tipos, sin embargo, en algunos otros tipos, el shell predeterminado utilizado es el mismo que el de inicio de sesión para ejecutarlo. La cuestión es: no deje que el sistema decida el shell, siempre proporcione el shell que desea en la primera línea.

Gurú
fuente
1
sí ... puede que mi shell actual invoque un shell predeterminado para el script de shell que no tiene números mágicos.
user1678213
1
@ user1678213 Sí, es su shell (y no el núcleo) lo que está haciendo esto.
Gilles 'SO- deja de ser malvado'
1
Creo que POSIX exige que / bin / sh se use en este caso.
vonbrand
2
@vonbrand Este es un error común. POSIX no exige que el shell POSIX sea /bin/sh, solo para ser el primer shejecutable encontrado al explorar una RUTA conforme.
jlliagre
3
Eso es incorrecto, nunca se utiliza el "shell de inicio de sesión" para ejecutarlo. Sin embargo, lo que puede suceder es que el intérprete de llamada (si el script se llama desde un intérprete de comandos) puede tener un hijo propio interpretándolo.
Stéphane Chazelas
8

Cuando ejecuta un programa, el núcleo verifica si comienza por alguna secuencia de bytes mágicos . Si el archivo ejecutable comienza con #!, el núcleo interpreta el resto de la línea como un nombre de intérprete. Si el archivo ejecutable comienza con \177ELF(donde \177está el byte 127), carga el archivo como un ejecutable ELF ; Ese es el tipo normal en la mayoría de los sistemas Unix hoy en día.

Si el núcleo no reconoce el formato del archivo, se niega a ejecutar el archivo y devuelve el error ENOEXEC (error de formato Exec). Cuando el shell se da cuenta de eso, se encarga de ejecutar el programa como un script de shell.

Para presenciar esto en acción, agregue algunos comandos a su script:

ps l $$
ls -l /proc/$$/exe
echo hello

(Esto es para Linux, ajústelo para otras unidades). Luego intente ejecutar ese script desde varios shells. Verá que algunos shells generan nuevas instancias de sí mismos para ejecutar el script (bash, ksh93) mientras que otros generan /bin/sh(dash, pdksh, zsh).

Gilles 'SO- deja de ser malvado'
fuente
¿Qué busco con tu ls -lcomando? Esto: lrwxrwxrwx 1 i 0 Oct 11 05:15 exe -> /bin/bash-? Si es así, ¿qué dice? Además, noté que tenía SHELL=/bin/bashencendido env, pero cambiarlo no parecía cambiar el comportamiento. Tal vez no está relacionado?
Emanuel Berg
parece que está cambiando la variable de shell "SHELL". Si es así, solo está cambiando el valor de la variable de shell SHELL. No cambiará su shell. Para cambiar su shell, edite el archivo / etc / passwd.
user1678213
2
@EmanuelBerg Sí (debería haber escrito ls -l /proc/$$/exe, de hecho). Los exeenlaces apuntan al shell que está ejecutando su script. Cuando ejecutas tu script, verás que es bash el que interpreta el script. Si lo ejecuta, por ejemplo, pdksh, se ejecuta /bin/sh. No conozco ningún shell que use la SHELLvariable de entorno o el shell de inicio de sesión en esa circunstancia.
Gilles 'SO- deja de ser malvado'
2
@ user1678213 Cambiar el shell /etc/passwdcambia lo que se ejecuta al iniciar sesión a través de SSH o en una consola de texto. No cambia qué shell podría ejecutar scripts.
Gilles 'SO- deja de ser malvado'
2
@ user1678213 Verifiqué lo que escribí aquí ejecutando pruebas. Ninguno de los proyectiles que probé buscó /etc/passwdpara decidir qué shell usar, se bifurcaron o se ejecutaron /bin/sh.
Gilles 'SO- deja de ser malvado'
-2

Probablemente sea una de las siguientes 3 posibilidades:

  1. Está llamando al script directamente con el intérprete, IE: bash script.sh

  2. El nombre del archivo de script tiene una extensión .sh, que hace que el sistema busque el programa predeterminado para este tipo de archivo

  3. El entorno de shell que está utilizando está ejecutando el 'eco' por sí mismo, ya que solo puedo adivinar que el archivo de script es ejecutable. Si, por ejemplo, usará un shell bash y tiene un comando en su archivo que solo usa ksh, verá que no funcionará.

¡Buena suerte!

Bizna
fuente
3
ni lo llamé con bash ni con ninguna extensión.
user1678213
1
y el entorno de shell no lo está ejecutando porque cuando invoco el comando ps después de invocar mi script. El comando ps muestra dos procesos bash, lo que significa que hay dos bash ejecutándose. uno es mi shell bash de inicio de sesión y el otro es bash para mi script_script básico
user1678213
1
2: el núcleo no hará nada por el estilo. Zsh puede hacerlo, y bash puede ser forzado a hacerlo. 3: Sí, pero varía un poco entre conchas, mira mi respuesta.
Gilles 'SO- deja de ser malvado'