Pourquoi avez-vous besoin de mettre #! / Bin / bash au début d'un fichier de script?

487

J'ai déjà fait des scripts Bash et ils se sont tous bien déroulés sans #!/bin/bashau début.

Quel est l'intérêt de le mettre? Les choses seraient-elles différentes?

Aussi, comment prononcez-vous #? Je sais que cela !se prononce comme "coup".

Comment se #!prononce?

noeud ninja
la source
8
Vous n'en avez pas besoin et vous ne devriez pas, sauf si vous n'avez pas le choix. Utilisez '#! / Bin / sh' pendant que vous le pouvez et découvrez la différence entre un shell (POSIX) et bash. Il arrivera un jour avant que votre CV ne s'allonge trop longtemps lorsque vous vous retrouverez sur un système avec un shell différent et que vous souhaitiez toujours que vos scripts fonctionnent.
Jens
50
Il est prononcé "Hash-Bang" ou "She-Bang".
Beachhouse
22
Je pense qu'il convient de noter que cela n'est exécuté que si vous exécutez votre script en tant qu'exécutable. Donc, si vous définissez l'indicateur exécutable, puis tapez ./yourscript.extension, par exemple, ./helloworld.pyou ./helloworld.sh, il recherchera l'interpréteur sur cette ligne supérieure, ce qui serait #!/bin/pythonou !#/bin/bash, alors que lors de l'exécution du script comme python helloworld.py, la première ligne ne sera pas observée car elle est commentée en dehors. Il s'agit donc d'une séquence spéciale pour le shell / noyau.
JFA
@JFA y a-t-il un changement de séquence entre bash et python, lors de l'utilisation de! # Pour python et #! pour bash?
AAI
1
@AjeyaAnand non, c'était une erreur de frappe, bonne capture
JFA

Réponses:

426

C'est une convention donc le shell * nix sait quel type d'interprète exécuter.

Par exemple, les anciennes versions d'ATT par défaut étaient sh (le shell Bourne), tandis que les anciennes versions de BSD étaient par défaut csh (le shell C).

Même aujourd'hui (où la plupart des systèmes exécutent bash, le "Bourne Again Shell" ), les scripts peuvent être en bash, python, perl, ruby, PHP, etc., etc. Par exemple, vous pouvez voir #!/bin/perlou #!/bin/perl5.

PS: Le point d'exclamation ( !) est affectueusement appelé "bang" . Le symbole de commentaire du shell ( #) est parfois appelé "hachage" .

PPS: N'oubliez pas - sous * nix, associer un suffixe à un type de fichier n'est qu'une convention , pas une "règle" . Un exécutable peut être un programme binaire, n'importe lequel d'un million de types de scripts et d'autres choses également. D'où la nécessité de #!/bin/bash.

paulsm4
la source
1
J'ai découvert quelque chose d'autre utile, $ #. Comment ça s'appelle?
node ninja
91
Le shebang n'est pas une convention shell , il est interprété par le noyau lors de la gestion de l' execve(2)appel système; donc le shebang est une convention de noyau , pas un shell.
Basile Starynkevitch
10
En outre, cela aide certains éditeurs comme Vim à déterminer la langue de mise en évidence de la syntaxe si le fichier n'a pas d'extension. Sans le shebang, Vim affichera un script bash identique au fichier texte brut.
Aaron Blenkush
1
Je me demande si vous avez besoin d'ajouter #!/bin/shdes choses comme .profileet d'autres choses qui fonctionne OnLoad
Kolob Canyon
5
Alors ... hash-bang-slash-bin-slash-bash ?
Bernat
135

Pour être plus précis le shebang #! , quand il s'agit des deux premiers octets d'un exécutable (x mode ), est interprété par l' appel système execve (2) (qui exécute des programmes). Mais la spécification POSIX pourexecve ne mentionne pas le shebang.

Il doit être suivi d'un chemin de fichier d'un exécutable d'interpréteur (que BTW pourrait même être relatif, mais le plus souvent est absolu).

Une bonne astuce (ou peut-être pas si agréable ) pour trouver un interprète (par exemple python) dans l'utilisateur $PATHest d'utiliser le envprogramme (toujours /usr/bin/envsur tous les Linux) comme par exemple

 #!/usr/bin/env python

Tout exécutable ELF peut être un interpréteur. Vous pouvez même utiliser #!/bin/catou #!/bin/truesi vous le souhaitez! (mais ce serait souvent inutile)

Basile Starynkevitch
la source
8
Voir cette question pour une discussion sur le #!/usr/bin/envhack.
Keith Thompson
si je veux passer un argument à python, comment dois-je le faire #!/usr/bin/env bash -x? Comment je fais ça ?
indianwebdevil
c'est simple, je l'ai moi-même trouvé, il suffit d'ajouter le paramètre après cela#!/usr/bin/env bash -x
indianwebdevil
bashest presque toujours au /bin/bashpoint donc votre cul devrait l'être#!/bin/bash -x
Basile Starynkevitch
50

Cela s'appelle un shebang . Dans unix-parler, # est appelé sharp (comme dans la musique) ou hash (comme les hashtags sur twitter), et! est appelé bang. (Vous pouvez en fait référencer votre commande shell précédente avec !!, appelé bang-bang). Donc, une fois assemblé, vous obtenez haSH-BANG, ou shebang.

La partie après le #! indique à Unix quel programme utiliser pour l'exécuter. S'il n'est pas spécifié, il essaiera avec bash (ou sh, ou zsh, ou quelle que soit votre variable $ SHELL) mais s'il est là, il utilisera ce programme. De plus, # est un commentaire dans la plupart des langues, donc la ligne est ignorée lors de l'exécution suivante.

austin1howard
la source
2
Si je suis déjà dans bash, démarre-t-il une autre instance bash s'il voit #! / Bin / bash? Et si je suis déjà en bash et que je le laisse de côté? Y a-t-il une différence?
node ninja
2
@javascriptninja dans tous les cas, il démarre un nouveau shell bash. Dans le cas de bash, il n'y a vraiment aucune différence, tant que vous utilisez déjà bash. Le shebang n'a vraiment d'importance que si (a) vous devez exécuter quelque chose qui n'est pas seulement un shell, comme python ou perl, ou (b) vous n'utilisez pas le shell bash (c'est-à-dire que vous utilisez zsh) mais vous devez exécuter quelque chose qui nécessite d'être exécuté dans bash.
austin1howard
Cependant, à mon avis, c'est une bonne pratique d'inclure le shebang, juste pour que quelqu'un lisant le code sache ce qui se passe.
austin1howard
2
Mauvais: execve(2)syscall n'utilise pas la $SHELLvariable. C'est le noyau qui interprète le shebang.
Basile Starynkevitch
1
@BasileStarynkevitch qui est correct, le chargeur elfe dans le noyau interprète le shebang. Je disais que $ SHELL serait utilisé si aucun shebang n'était fourni.
austin1howard
19

Le shebang est une directive adressée au chargeur pour utiliser le programme spécifié après le #!comme interpréteur du fichier en question lorsque vous essayez de l'exécuter. Donc, si vous essayez d'exécuter un fichier appelé foo.shqui a #!/bin/bashen haut, la commande réelle qui s'exécute est /bin/bash foo.sh. Il s'agit d'une manière flexible d'utiliser différents interprètes pour différents programmes. C'est quelque chose implémenté au niveau du système et l'API au niveau de l'utilisateur est la convention shebang.

Il convient également de savoir que le shebang est un nombre magique - un chiffre lisible par l'homme qui identifie le fichier comme un script pour l'interpréteur donné.

Votre point à ce sujet "fonctionne" même sans le shebang est uniquement parce que le programme en question est un script shell écrit pour le même shell que celui que vous utilisez. Par exemple, vous pourriez très bien écrire un fichier javascript puis mettre un #! /usr/bin/js(ou quelque chose de similaire) pour avoir un "script shell" javascript.

Noufal Ibrahim
la source
18

Le système d'exploitation utilise le shell par défaut pour exécuter votre script shell. donc en mentionnant le chemin du shell au début du script, vous demandez au système d'exploitation d'utiliser ce shell particulier. Il est également utile pour la portabilité .

Balaswamy Vaddeman
la source
15

Chaque distribution a un shell par défaut. Bash est la valeur par défaut sur la plupart des systèmes. S'il vous arrive de travailler sur un système qui a un shell par défaut différent, les scripts peuvent ne pas fonctionner comme prévu s'ils sont écrits spécifiquement pour Bash.

Bash a évolué au fil des ans en prenant le code de kshet sh.

L'ajout en #!/bin/bashtant que première ligne de votre script, indique au système d'exploitation d'appeler le spécifié shellpour exécuter les commandes qui suivent dans le script.

#! est souvent appelé "hash-bang", "she-bang" ou "sha-bang".

jaypal singh
la source
9

Cela s'appelle un shebang . Il se compose d'un signe numérique et d'un caractère de point d'exclamation (#!), Suivi du chemin complet vers l'interpréteur tel que / bin / bash. Tous les scripts sous UNIX et Linux s'exécutent à l'aide de l'interpréteur spécifié sur une première ligne.

Uday Sawant
la source
0

Il peut être utile à quelqu'un qui utilise un système différent qui n'a pas cette bibliothèque facilement disponible. Si cela n'est pas déclaré et que certaines fonctions de votre script ne sont pas prises en charge par ce système, vous devez déclarer # / bin / bash. J'ai rencontré ce problème avant au travail et maintenant je l'inclus comme pratique.

Beardy
la source