bash - meaning - ¿Puede un script ser utilizado como un intérprete por el#! línea hashbang?
shebang meaning (4)
Intento escribir un script bash que se comporte como un intérprete básico, pero parece que no funciona: el intérprete personalizado no parece invocado. ¿Qué estoy haciendo mal?
Aquí hay una configuración simple que ilustra el problema:
/bin/interpreter
: [propiedad de root; ejecutable]
#!/bin/bash
echo "I am an interpreter running " $1
/Users/zeph/script
es propiedad de mí y es ejecutable:
#!/bin/interpreter
Here are some commands for the custom interpreter.
Por lo que entiendo acerca de la mecánica de hashbangs, el script debería ser ejecutable de la siguiente manera:
$ ./script
I am an interpreter running ./script
Pero esto no funciona. En cambio, sucede lo siguiente:
$ ./script
./script: line 3: Here: command not found
... Parece que /bin/bash
está tratando de interpretar el contenido de ./script
. ¿Qué estoy haciendo mal?
Nota: Aunque parece que /bin/interpreter
nunca se invoca, obtengo un error si no existe:
$ ./script
-bash: ./script: /bin/interpreter: bad interpreter: No such file or directory
(Segunda nota: si hace alguna diferencia, estoy haciendo esto en MacOS X).
¡No puedes usar un script directamente como #!
intérprete, pero puede ejecutar el guión indirectamente a través del comando env
usando:
#!/usr/bin/env /bin/interpreter
/usr/bin/env
es en sí mismo un binario, por lo que es un intérprete válido para #!
; y /bin/interpreter
puede ser cualquier cosa que desee (un guión de cualquier variedad, o binario) sin tener que poner conocimiento de su propio intérprete en el guión de llamada.
Hice una pregunta similar en comp.unix.shell que generó información pertinente.
Hubo una segunda rama del mismo hilo que llevó la idea más allá.
La solución de Unix más general es hacer que el punto shebang sea un ejecutable binario. Pero ese programa ejecutable podría ser tan simple como una sola llamada a execl()
. Ambos subprocesos conducen al origen de ejemplo C para un programa llamado gscmd, que es poco más que un derivador a execv("gs",...)
.
Lea la página de manual de execve
para su sistema. Dicta cómo se inician los scripts, y debe especificar que el intérprete en una línea hash-bang es un ejecutable binario.
Para que esto funcione, podría agregar el intérprete del intérprete (es decir, bash
) al shebang:
#!/bin/bash /bin/interpreter
Here are some commands for the custom interpreter.
bash
ejecutará su intérprete con la ruta del script en $1
como se esperaba.