Estoy definiendo un script de shell que un usuario debería en source
lugar de ejecutar.
¿Existe una forma convencional o inteligente de indicarle al usuario que este es el caso, por ejemplo a través de una extensión de archivo?
¿Hay algún código de shell que pueda escribir en el archivo mismo, lo que hará que repita un mensaje y se cierre si se ejecuta en lugar de obtenerlo, de modo que pueda ayudar al usuario a evitar este error obvio?
x
, que solo contiene el comando. your-script-to-be-sourced
, está bien, pero si desea ejecutarlobash your-script-to-be-sourced
, ¿debería estar prohibido? ¿Cuál es el punto de esta restricción?env
variables y las deja como resultado de la secuencia de comandos de facto . Un novato se quedará atrapado durante días con el rompecabezas si les permite ejecutar.if __name__ == '__main__'
?Respuestas:
Suponiendo que está ejecutando bash, coloque el siguiente código cerca del inicio del script que desea que se obtenga pero no se ejecute:
En bash,
${BASH_SOURCE[0]}
contendrá el nombre del archivo actual que el shell está leyendo independientemente de si se está obteniendo o ejecutando.Por el contrario,
$0
es el nombre del archivo actual que se está ejecutando.-ef
prueba si estos dos archivos son el mismo archivo. Si es así, alertamos al usuario y salimos.Ni
-ef
tampocoBASH_SOURCE
son POSIX. Si bien-ef
es compatible con ksh, yash, zsh y Dash,BASH_SOURCE
requiere bash. Enzsh
, sin embargo,${BASH_SOURCE[0]}
podría ser reemplazado por${(%):-%N}
.fuente
echo "Usage: source \"$myfile\""
source
no es portátil. Teniendo en cuenta que esta respuesta es específica de bash, no es tan mala, pero es un buen hábito usar el portátil.
Un archivo no ejecutable puede obtenerse pero no ejecutarse, por lo que, como primera línea de defensa, no establecer el indicador ejecutable debería ser una buena pista ...
Editar: truco con el que me topé: hacer que el shebang sea cualquier ejecutable que no sea un intérprete de shell,
/bin/false
hace que el script devuelva un error (rc! = 0)fuente
bash somefile.sh
...bash
(vd perl, python, awk ...), entonces ha buscado la fuente y ha visto el comentario que dice no hacerlo :)somefile.pl
y Python comosomefile.py
, lo que no, probablemente no he leído los comentarios (que son los que, incluso, de todos modos?) Ybash somefile.sh
es más corto de lo que escribirchmod +x somefile.sh; ./somefile.sh
...bash
, primero intentaránexecve
un archivo, pero si eso falla, inspeccionan el archivo manualmente y lo interpretan manualmente#!
e invocan a través de ese intérprete: este es un legado de los días en que#!
era un espacio puramente de usuario convención, en lugar de ser manejado por el núcleo mismo. Creo quebash
, al menos, no hará esto para archivos no ejecutables, pero no sé si es portátil esperar un comportamiento tan sensato de todos los shells de los que el usuario podría invocar el script.bash
quebash script.sh
pueden ser peligrosos.Hay varios métodos sugeridos en esta publicación de Stack Overflow , de los cuales, me gustó el basado en funciones sugerido por Wirawan Purwanto y mr.spuratic mejor:
Para que pueda agregar al inicio del script:
fuente
Asumiendo que es inútil, en lugar de perjudicial, ejecutar el script, puede agregar
hasta el final del guión.
return
fuera de una función tiene un código de salida distinto de cero a menos que el archivo se obtenga.fuente
return 2>/dev/null; echo "$0: This script must be sourced" 1>&2; exit 1
Cuando obtiene un script de shell, se ignora la línea shebang . Al colocar un shebang no válido, puede alertar al usuario de que el script se ejecutó erróneamente:
El mensaje de error será este:
El nombre del argumento (arbitrario) ya proporciona una pista fuerte, pero el mensaje de error aún no es 100% claro. Podemos arreglar esto con un script de utilidad
source-this-script
que se coloca en algún lugar de suPATH
:Ahora, el mensaje de error será este:
Comparación con otros enfoques
En comparación con las otras respuestas, este enfoque solo requiere cambios mínimos en cada script (y tener una línea shebang ayuda con la detección del tipo de archivo en los editores y especifica el dialecto del script de shell, por lo que incluso hay beneficios). La desventaja es un mensaje de error algo poco claro, o la adición (única) de otro script de shell.
Sin embargo, no evita la invocación explícita a través de
bash path/to/script.sh
(¡gracias @muru!).fuente
bash some/script.sh
, lo que también ignoraría el shebang.#!/bin/echo 'You must source this script!'
o algo así.