J'ai un exemple de script (le crédit va à kos ):
#!/bin/bash
cat <(cat /etc/lsb-release)
Je sauvegarde ce script sous le nom somename.sh dans mon répertoire personnel.
Maintenant, j'essaie d'ouvrir ce fichier de trois manières différentes:
sh somename.sh
bash somename.sh
./somename.sh
Donc, j'ai deux questions:
Pourquoi les sorties des commandes ci-dessus sont-elles différentes alors qu'elles exécutent le même script?
sh produit une erreur de syntaxe
bash renvoie le résultat souhaité
./ donne une erreur Permission Denied
Pourquoi est-il nécessaire de donner au script une autorisation d'exécution uniquement lors de l'exécution du script avec ./ et non nécessaire dans les autres cas?
Merci d'avance!
EDIT: La première partie pourrait être similaire à la dupliquer liée mais j'avais aussi une deuxième question.
Comme nous en avons discuté dans le chat:
sh script
génère une erreur car l'appel de l'interpréteur directement (dans ce cas, sh
) ignore Shebang et le script est exécuté dans sh
; sh
ne prend pas en charge les substitutions de processus (<([...])
), qui sont des bash-ismes, le script se ferme donc en cas d'erreur.
bash script
ne génère pas d'erreur car, même si Shebang est ignoré, le script est toujours exécuté dans Bash, qui prend en charge les substitutions de processus.
./script
génère une erreur car script
n'est pas exécutable.
Pour exécuter un script avec ./
vous devez avoir le bit d'exécution pour votre utilisateur défini sur le script, il s'agit d'une contrainte du système d'exploitation.
La question est donc: pourquoi bash script
n'exige-t-il pas que le bit d'exécution soit défini pour votre utilisateur sur script
?
En effet, lors de l'exécution de bash script
, le script est lu par Bash et Bash a le bit d'exécution défini pour votre utilisateur.
Cela signifie que Bash, ayant l'autorisation d'exécuter du code, peut "contourner" la contrainte du système d'exploitation sur ce script, et tous les besoins de script doivent être lisibles par Bash.
sh
est un lien symbolique vers dash
Shell et génère une erreur de syntaxe car il n'y a pas de syntaxe de <( . . .)
dans sh
. C'est seulement en bash (et en zsh
et ksh
si je me souviens bien).
bash affiche le résultat souhaité, car sa syntaxe est correcte, rien à redire
./ donne une erreur Permission Denied parce que vous dites essentiellement "Hé, Shell, examinez les autorisations de ce fichier et examinez la première ligne (celle avec #!/bin/bash
) dans mon répertoire actuel et comprendre comment exécuter ce script pour moi ". (note latérale: si le script se trouvait dans un emplacement inclus dans votre variable $PATH
, il vous suffirait alors d'exécuter myScriptName.sh
et le tour est joué, mais l'idée serait la même, nous devons vérifier exec autorisations et quel interprète utiliser)
Avant, vous utilisiez bash
et dash
et leur disiez de lire les commandes à partir d'un fichier. bash
et dash
sont exécutables cette fois, pas le script. Le script est maintenant source de commandes, un paramètre. Les autorisations de lecture sont toujours définies pour tous les utilisateurs, de sorte que les shells le liront.
En général, sh
, ash
, dash
, bash
, csh
, tcsh
, zsh
... sont tous des coquilles avec leurs propres syntaxes et caractéristiques. Il y a quelques compatibilités mais elles sont orientées [ 1 ]: un bash
Shell exécutera un script sh
mais il n'est pas dit que le vice-versa . Une invocation sh
nécessite moins de ressources qu'une bash
. Pour un seul cas, ce n'est pas un problème, pour des milliers, cela devrait être le cas.
Façons d'exécuter.
Pour exécuter un fichier sous forme de programme sous Linux, qu’il s’agisse d’un script ou d’un script compilé, vous devez définir le bit d’exécution . [ 2 ] et il doit être inclus dans l’un des répertoires de votre _$PATH
_.
Si c’est un script, il peut être passé comme argument au shell relatif (sh
, bash
..._myfile.whatever
_): s’il est passé à Mauvais Shell vous pouvez obtenir un comportement incorrect et si vous êtes chanceux une erreur ; dans ce cas , il n’a pas besoin d’être exécutable car c’est comme si vous écriviez directement les lignes écrites dans le script dans le nouveau shell que vous appelez. Pour exécuter dans le même shell, vous pouvez utiliser plutôt _source myfile
_ ou _. myfile
_ équivalant à écrire ligne par ligne dans le shell actuel le contenu du script.
Emplacement
Si le programme exécutable n'est pas inclus dans votre chemin, vous devez spécifier où il peut être trouvé.
./
signifie uniquement le répertoire en cours de votre shell. _~/myfile.whatever
_ doit également adresser le fichier _myfile.whatever
_ dans votre répertoire personnel _~/
_./home/$USER/dir/myfile.whatever
_.myfile.whatever
_.Dans le cas où plusieurs exécutables partagent le même nom, la spécification du chemin d'accès complet déterminera celui que vous allez exécuter. _which mycommand
_ est capable de vous dire lequel sera exécuté maintenant (une fonction, un alias, un construit ou le premier trouvé dans votre chemin), mais il ne peut pas dire lequel sera exécuté ultérieurement ou à partir de un autre utilisateur. Si vous écrivez expressément le chemin complet, vous corrigerez cette ambiguïté. Il est utile d'exécuter une version spécifique d'un programme lorsque plusieurs versions sont installées simultanément ... et d'éviter les chevaux de Troie. Dans un script, il est toujours suggéré d'écrire _/bin/bash
_ au lieu de bash
.