Je définis un script shell qu'un utilisateur devrait source
exécuter plutôt que d'exécuter.
Existe-t-il un moyen conventionnel ou intelligent d'indiquer à l'utilisateur que c'est le cas, par exemple via une extension de fichier?
Existe-t-il un code shell que je peux écrire dans le fichier lui-même, ce qui entraînera l'écho d'un message et sa fermeture s'il est exécuté à la place de la source, afin d'aider l'utilisateur à éviter cette erreur évidente?
x
, qui ne contient que la commande. your-script-to-be-sourced
, tout va bien, mais s'il veut l'exécuter,bash your-script-to-be-sourced
cela devrait être interdit? Quel est le but de cette restriction?env
variables et les laisse comme sortie de script de facto . Un novice restera coincé pendant des jours avec le puzzle si vous lui permettez de s'exécuter.if __name__ == '__main__'
?Réponses:
En supposant que vous exécutiez bash, placez le code suivant au début du script que vous voulez extraire mais non exécuter:
Sous bash,
${BASH_SOURCE[0]}
contiendra le nom du fichier en cours de lecture par le shell, qu'il soit en cours d’exploitation ou non.En revanche,
$0
est le nom du fichier en cours d’exécution.-ef
teste si ces deux fichiers sont le même fichier. S'ils le sont, nous alertons l'utilisateur et sortons.Ni sont
-ef
niBASH_SOURCE
POSIX. While-ef
est pris en charge par ksh, yash, zsh et Dash,BASH_SOURCE
nécessite bash. Enzsh
, cependant,${BASH_SOURCE[0]}
pourrait être remplacé par${(%):-%N}
.la source
echo "Usage: source \"$myfile\""
source
n'est pas portable. Considérant que cette réponse est spécifique à Bash, ce n’est pas si grave, mais c’est une bonne habitude d’utiliser le portable.
Un fichier non-exécutable peut être recherché mais non exécuté. Par conséquent, en tant que première ligne de défense, le fait de ne pas définir l'indicateur d'exécutable devrait être un bon indice ...
Edit: astuce que je viens de trébucher: faire du shebang un exécutable qui n’est pas un interpréteur de shell,
/bin/false
fait que le script retourne une erreur (rc! = 0)la source
bash somefile.sh
...bash
(vd, perl, python, awk ...), alors vous avez regardé la source et vu le commentaire disant de ne pas le faire :)somefile.pl
et Pythonsomefile.py
, alors non, je n'ai probablement pas lu les commentaires (quels sont-ils, même, de toute façon?) Et ilsbash somefile.sh
sont plus courts à taper quechmod +x somefile.sh; ./somefile.sh
...bash
, essaieront d'abordexecve
un fichier, mais si cela échoue, ils l'inspectent manuellement et l'interprètent manuellement#!
et l'invoquent via cet interpréteur: il s'agit d'un héritage de l'époque où il#!
était purement utilisateur. convention, au lieu d’être gérée par le noyau lui-même. Dubash
moins, je pense que cela ne sera pas le cas pour les fichiers non exécutables, mais je ne sais pas s'il est portable d'attendre un comportement aussi sain d'esprit de tous les shells à partir desquels l'utilisateur pourrait appeler le script.bash
et que celabash script.sh
peut être dangereux.Il existe plusieurs méthodes suggérées dans ce message Stack Overflow , et j’ai aimé la méthode basée sur les fonctions suggérée par Wirawan Purwanto et mr.spuratic best:
Vous pouvez donc ajouter au début du script:
la source
En supposant que l’exécution du script soit inutile, plutôt que nuisible, vous pouvez ajouter
à la fin du script.
return
En dehors d'une fonction, le code de sortie est différent de zéro, sauf si le fichier est en cours d'acquisition.la source
return 2>/dev/null; echo "$0: This script must be sourced" 1>&2; exit 1
Lorsque vous sourcez un script shell, la ligne shebang est ignorée. En insérant un shebang non valide, vous pouvez avertir l'utilisateur que le script a été exécuté par erreur:
Le message d'erreur sera le suivant:
Le nom de l'argument (arbitraire) fournit déjà un indice fort, mais le message d'erreur n'est toujours pas clair à 100%. Nous pouvons résoudre ce problème avec un script utilitaire
source-this-script
placé quelque part dans votrePATH
:Maintenant, le message d'erreur sera ceci:
Comparaison avec d'autres approches
Comparée aux autres réponses, cette approche ne nécessite que des modifications minimes de chaque script (et avoir une ligne shebang facilite la détection du type de fichier dans les éditeurs et spécifie le dialecte du script shell, ce qui présente même des avantages). L'inconvénient est un message d'erreur quelque peu flou, ou l'ajout (ponctuel) d'un autre script shell.
Cela n'empêche cependant pas l'invocation explicite via
bash path/to/script.sh
(merci @muru!).la source
bash some/script.sh
, ce qui ignorerait également le shebang.#!/bin/echo 'You must source this script!'
ou quelque chose du genre.