59 votes

Comment le #! shebang travail?

Dans un script, vous devez inclure un #! sur la première ligne, suivie du chemin d'accès du programme à exécuter le script (par exemple: sh, perl).

Autant que je sache, l' # caractère indique le début d'un commentaire, et que la ligne est censé être ignorés par le programme à exécuter le script. Il semblerait que cette première ligne à un certain point, lire par quelque chose pour que le script soit exécuté par le programme approprié.

Quelqu'un pourrait veuillez jeter plus de lumière sur le fonctionnement de l' #!?

Je suis vraiment curieux de savoir à ce sujet, de sorte que le plus en profondeur la réponse la mieux.

60voto

Kevin Panko Points 4481

Lecture recommandée:

Le noyau unix programme du chargeur est responsable pour cela. Lors de l' exec() est appelé, il demande au noyau de charger le programme dans le fichier à son argument. Il vérifiera ensuite les 16 premiers bits du fichier à voir quel format de fichier exécutable dont il dispose. Si elle constate que ces bits sont #! il va utiliser le reste de la première ligne du fichier pour trouver le programme qui elle devrait se lancer, et il fournit le nom du fichier qu'il était en train de lancer (le script) que le dernier argument pour le programme interprète.

L'interprète exécute alors que la normale, et traite l' #! comme une ligne de commentaire.

18voto

leonbloy Points 27119

Disons que nous avons ce fichier xxx.pl :

#!/usr/bin/perl
use strict;
# this is a comment line in perl
print("hi!\n");
exit(0);

Si vous appelez $ perl xxx.pl , l'interprète (perl) pour charger le fichier et de l'interpréter comme un fichier source. La première ligne sera pour lui juste un commentaire, pour être ignoré, de même que la troisième ligne.

Ce qui se passe à la place si xxx.pl est de le rendre exécutable et directement invoquée : $ ./xxx.pl? Ici, c'est le shell (par exemple. /bin/bash ) le programme qui charge le fichier et tente de l'exécuter. Pour cela, il lit les premiers octets (rappelez-vous, il ne sait toujours pas si xxx.pl est une source perl, python source, un script shell, ou un binaire exécutable ou quoi), il découvre la magie #! octets, et puis il dit lui-même :

"Aha! C'est le fameux beau spectacle! Ensuite, ce fichier doit être, pas un binaire exécutable, mais un texte script ou la source que je dois invoquer via un programme. Quel est le programme? Nous allons lire le reste de une première ligne (jusqu' \n) et le savoir. Ah, /usr/bin/perl hein? Ok, je vais l'appeler que exécutable et de transmettre cette "xxx.pl' fichier argument.

Il appelle alors /usr/bin/perl xxx.pl. Et là vous l'avez.

Mise à jour: Kevin souligne à juste titre, l'intelligence de traiter le shebang va en fait en dessous de la coque, à l'intérieur du processus de chargeur du noyau. En effet, si vous lancez une commande à partir d'un programme C par le biais de l'un de la exec() des fonctions de la famille (pas de shell impliqué) le shebang seront également traitées.

10voto

stakx Points 29832

Histoire courte: Le shebang (#!) de la ligne est lue par le shell (par exemple, sh, bash, etc.) le système d'exploitation du programme loader. Alors qu'il a officiellement ressemble à un commentaire, le fait que ce sont les deux premiers octets d'un fichier des marques de l'intégralité du fichier comme un fichier texte et en tant que script. Le script sera transmis à l'exécutable mentionné sur la première ligne après le shebang. Voilà!


Légèrement plus long de l'histoire: Imaginez que vous avez votre script, foo.sh, avec le bit d'exécution (x) ensemble. Ce fichier contient par exemple les suivantes:

#!/bin/sh

# some script commands follow...:
# *snip*

Maintenant, sur votre coquille, vous tapez:

> ./foo.sh

Edit: Veuillez lire également les commentaires ci-dessous après ou avant de lire la suite! Comme il s'avère, j'ai eu tort. C'est apparemment pas le shell qui passe par le script à la cible interprète, mais le système d'exploitation (noyau) lui-même.

Rappelez-vous que vous tapez à l'intérieur du processus de shell (supposons que c'est le programme /bin/sh). Par conséquent, que les contributions devront être traitées par le programme. Il interprète cette ligne de commande, car il découvre que la première chose est entré sur la ligne est le nom d'un fichier qui existe réellement et qui a le bit d'exécution(s) ensemble.

/bin/sh puis commence à lire le contenu du fichier et découvre le shebang (#!) dès le tout début du fichier. Pour la coquille, c'est un jeton ("nombre magique"), par laquelle elle sait que le fichier contient un script.

Maintenant, comment fait-il savoir quel langage de programmation le script est écrit? Après tout, vous pouvez exécuter des scripts Bash, Perl, Python scripts, ... Tout le shell sait jusqu'à présent, c'est qu'il est à la recherche à un fichier de script (qui n'est pas un fichier binaire, mais un fichier texte). Ainsi, il lit l'entrée suivante à la première rupture de ligne (qui sera résultat en /bin/sh, à comparer ci-dessus). C'est l'interprète à laquelle le script sera transmis pour exécution. (Dans ce cas particulier, la cible de l'interprète est le shell lui-même, afin de ne pas avoir à invoquer un nouveau shell pour le script; il traite simplement le reste du fichier de script lui-même.)

Si le script était destiné, par exemple, /bin/perl, tout ce que l'interpréteur Perl serait (éventuellement) avoir à faire est de regarder si la ligne shebang vraiment mentionne l'interpréteur Perl. Si non, l'interpréteur Perl sait qu'il ne peut pas exécuter ce script. Si, en effet, l'interpréteur Perl est mentionné dans la ligne shebang, il lit le reste du fichier de script et l'exécute.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X