Bash: ¿detectar ejecutar vs fuente en un script?

19

Tengo un script que está plagado alrededor de mi sistema de archivos (efecto secundario de un proceso de compilación) que establece algunas variables de entorno globales (LD_LIBRARY_PATH, PATH, ROOTDIR, etc.) que deben estar en mi shell para una operación adecuada. Por supuesto, eso significa que necesito source script.sho . script.shpara que funcione, y no ./script.sh(lo que generaría un nuevo shell y no establecería las variables en mi shell actual).

¿Hay algo que pueda agregar al script para evitar (o advertir) que alguien se ejecute ./script.sh?

Yeraze
fuente

Respuestas:

15

En un script de shell, $0es el nombre del script que se está ejecutando actualmente. Puede usar esto para saber si está recibiendo o ejecuta de esta manera:

if [[ "$(basename -- "$0")" == "script.sh" ]]; then
    echo "Don't run $0, source it" >&2
    exit 1
fi
Mikel
fuente
5

La forma más simple bashes:

if [ "$0" = "$BASH_SOURCE" ]; then
    echo "Error: Script must be sourced"
    exit 1
fi

$BASH_SOURCE siempre contiene el nombre / ruta del script.

$0 solo contiene el nombre / ruta del script cuando NO se obtiene.

Entonces, cuando coinciden, eso significa que el script NO fue originado.

wisbucky
fuente
1

Esto ha sido discutido en SO . La respuesta más votada por @barroyo dice usar

[[ "${BASH_SOURCE[0]}" != "${0}" ]] && echo "script ${BASH_SOURCE[0]} is being sourced ..."
serv-inc
fuente
@will: El manual dice: Una variable de matriz cuyos miembros son los nombres de los archivos de origen donde se definen los nombres de función de shell correspondientes en la variable de matriz FUNCNAME. ¿Cómo funciona una función?
serv-inc
1

Otra opción puede ser eliminar los permisos de ejecución. En ese caso, no se puede ejecutar, pero aún se puede obtener.

Jelmer
fuente
1
Esto esta incompleto. Aún puede ejecutar scripts bash scriptindependientemente de la marca de ejecución en un script. También bajo Cygwin (¿cuenta esto?) No puede quitar las banderas de ejecución.
Tino
0

Además de marcar $ 0 ( respuesta de Mikel ) puede ser útil para cambiar la extensión de .sh a .src, por ejemplo. Ayudará a entender a cualquiera que no deba ejecutar este script.

Victor Sizov
fuente
0

Crea un intérprete personalizado source_reminder:

#!/bin/sh
printf "%s\n" "Source me!" >&2
exit 1

No te olvides de hacerlo ejecutable. Luego, úsalo en tu script:

#!/path/to/your/source_reminder
foo
bar
whatever

Ahora, si ejecuta el script sin fuente, el recordatorio hará su trabajo.

Kamil Maciorowski
fuente
Buena atrapada. #!/bin/echo do not executeo #!/bin/falseo #!/usr/bin/awk BEGIN { print "you must source " ARGV[1]; exit(1) }. Sin embargo, esto no detecta el caso donde el script se ejecuta con algo como sh script(ya que esto ignora el Shebang).
Tino