3 votos

¿Cómo conseguir que `"#!/opt/homebrew/bin/bats"` funcione según lo esperado?

Después de instalar https://github.com/bats-core/bats-core a través de brew install bats-core en Sonoma, creé un script de bats bash.

Cuando la primera línea es #!/usr/bin/env bats, funciona bien.

Pero cuando la primera línea es #!/opt/homebrew/bin/bats, da un error con @test: command not found. Curiosamente, al ejecutar /opt/homebrew/bin/bats example.bats funciona bien.

¿Cómo puedo hacer que #!/opt/homebrew/bin/bats funcione igual que cuando uso explícitamente /opt/homebrew/bin/bats en la línea de comandos?

3voto

bats es un script de shell, pero las shebangs (#!) solo pueden apuntar a binarios, no a scripts de shell. La razón de esto es que la llamada al sistema execve() (que lee un archivo para ser ejecutado) no maneja la ejecución indirecta, esperando ya sea un binario o un archivo que comience con #! /ruta/al/binario.

Esto hace que #!/usr/bin/env bats sea la única forma de hacer que estos scripts funcionen.


De execve(2):

execve() transforma el proceso que llama en un nuevo proceso. El nuevo proceso se construye a partir de un archivo ordinario, cuyo nombre es apuntado por path, llamado el archivo del nuevo proceso. Este archivo es ya sea un archivo objeto ejecutable, o un archivo de datos para un intérprete. Un archivo objeto ejecutable consiste en un encabezado identificativo, seguido por páginas de datos que representan el programa inicial (texto) y páginas de datos inicializados. Páginas adicionales pueden ser especificadas por el encabezado para ser inicializadas con datos de cero; consultar a.out(5).

Un archivo de intérprete comienza con una línea de la forma:

    #! intérprete [arg ...]

Cuando un archivo de intérprete es execve()'d, el sistema ejecuta el intérprete especificado. Si se especifican argumentos opcionales, estos se convierten en el primer (segundo, ...) argumento del intérprete. El nombre del archivo originalmente ejecutado con execve se convierte en el argumento subsecuente; de lo contrario, el nombre del archivo originalmente ejecutado con execve es el primer argumento. Los argumentos originales de la invocación del intérprete se desplazan para convertirse en los argumentos finales. El argumento cero, normalmente el nombre del archivo ejecutado con execve, se mantiene sin cambios.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X