web-dev-qa-db-fra.com

Quelle est la différence entre exécuter "bash script.sh" et "./script.sh"?

Si script.sh est juste quelque chose de typique comme

#!/bin/bash
echo "Hello World!"

Existe-t-il un moyen préféré d'exécuter le script? Je pense que vous devez d'abord le modifier pour qu'il devienne exécutable?

43
user72136

Pour votre script spécifique, dans les deux cas, cela fonctionnera, sauf que ./script.sh nécessite une exécution et des bits lisibles, tandis que bash script.sh nécessite uniquement un bit lisible.


La raison de la différence d'exigence des autorisations réside dans la façon dont le programme qui interprète votre script est chargé:

  • ./script.sh oblige votre shell à exécuter le fichier comme s'il s'agissait d'un exécutable standard.

Le shell se fourche lui-même et utilise un appel système (par exemple execve) pour que le système d'exploitation exécute le fichier dans le processus forké. Le système d'exploitation vérifiera les autorisations du fichier (par conséquent, le bit d'exécution doit être défini) et transmettra la demande au programme de chargement , qui examine le fichier et détermine comment l'exécuter. Sous Linux, les exécutables compilés commencent par un ELF nombre magique, tandis que les scripts commencent par un #! ( hashbang ). Un en-tête de hashbang signifie que le fichier est un script et doit être interprété par le programme spécifié après le hashbang. Cela permet à un script lui-même de dire au système comment interpréter le script.

Avec votre script, le programme de chargement exécutera /bin/bash et passez ./script.sh comme argument de ligne de commande.

  • bash script.sh fait exécuter votre Shell bash et passe script.sh comme argument de ligne de commande

Ainsi, le système d'exploitation chargera bash (sans même regarder script.sh, car ce n'est qu'un argument de ligne de commande). Le processus bash créé interprétera alors le script.sh car il est passé comme argument de ligne de commande. Parce que script.sh n'est lu que par bash en tant que fichier normal, le bit d'exécution n'est pas requis.


Je recommande d'utiliser ./script.sh cependant, car vous ne savez peut-être pas de quel interpréteur le script a besoin. Laissez donc le chargeur de programme déterminer cela pour vous.

57
hellodanylo

bash script.sh appelle le script directement à l'aide de bash.
./script.sh utilise le Shebang #!/bin/bash pour déterminer comment exécuter.

Si vous voulez vraiment savoir, quel binaire est exécuté si vous faites un bash script.sh vous pourriez découvrir avec which bash.

Donc, dans votre exemple, cela ne fait aucune différence. Oui, vous devez chmod +x script.sh pour pouvoir l'exécuter directement via ./script.sh.

18
xx4h

Créez un fichier Delete_Self.sh comme ceci:

 #!/bin/rm

 echo I am still here!

Exécutez ce script en tant que sh Delete_Self.sh vous verrez "Je suis toujours là!" retentit en retour.

Rendez-le exécutable et exécutez-le en tant que ./Delete_Self.sh vous ne verrez rien en écho, tandis que le fichier Delete_Self.sh lui-même a disparu.

Donc, la différence est que:

  • bash script.sh ignorera le #! car bash est spécifié comme programme pour exécuter script.sh.
  • ./script.sh lira le #! pour déterminer le programme à exécuter script.sh.
4
David

En plus des autres réponses, connaître la différence entre exécuter un script via ./script.sh (i) et source ./script.sh (ii) est utile - La version (i) crée un nouveau shell dans lequel exécuter la commande, tandis que (ii) l'exécute dans le shell actuel - qui peut être obligatoire si l'exécutable change les variables d'environnement qui doivent être préservées après la sortie de l'exécutable. Par exemple, pour activer un environnement conda python), les éléments suivants doivent être utilisés:

source activate my_env

N.B. Une autre alternative à source que vous pouvez rencontrer est le . intégré, c'est-à-dire.

. activate my_env
1
einonm