Que fait exactement "/usr/bin/env node" au début des fichiers nodes?
j'avais vu cette ligne #!/usr/bin/env node
au début de quelques exemples dans nodejs
et j'avais googlé sans trouver aucun sujet qui pourrait répondre à la raison de cette ligne.
la nature des mots ne rend pas la recherche facile.
j'avais lu récemment des livres javascript
et nodejs
et je ne m'en souvenais pas.
si vous voulez un exemple, vous pouvez voir le RabbitMQ
officiel tutoriel , ils l'ont dans presque tous leurs exemples, en voici un:
#!/usr/bin/env node
var amqp = require('amqplib/callback_api');
amqp.connect('amqp://localhost', function(err, conn) {
conn.createChannel(function(err, ch) {
var ex = 'logs';
var msg = process.argv.slice(2).join(' ') || 'Hello World!';
ch.assertExchange(ex, 'fanout', {durable: false});
ch.publish(ex, '', new Buffer(msg));
console.log(" [x] Sent %s", msg);
});
setTimeout(function() { conn.close(); process.exit(0) }, 500);
});
Quelqu'un pourrait-il m'expliquer ce que signifie cette ligne?
quelle différence cela fait-il si je mets ou retire cette ligne? Dans quels cas ai-je besoin?
3 réponses
#!/usr/bin/env node
est une instance d'un ligne shebang : première ligne dans un fichier exécutable fichier de texte brut sur les plateformes de type Unix qui indique au système qu'interprète pour transmettre ce fichier à des fins d'exécution , via la ligne de commande à la suite de la magie #!
préfixe (appelé shebang ).
Note: Windows does not support shebang lines , de sorte qu'ils sont effectivement ignored là; sur Windows, il est uniquement une extension de fichier de fichier d'un fichier donné qui détermine ce que l'exécutable va l'interpréter. cependant, vous avez encore besoin d'eux dans le contexte de npm
. [1]
, discussion générale de shebang lines est limité aux plates-formes Unix-like:
dans la discussion suivante, je supposerai que le fichier contenant le code source pour l'exécution par noeud.js est simplement appelé file
.
-
vous besoin de cette ligne , si vous voulez invoquer un noeud.js source file directement , en tant qu'exécutable à part entière - cela suppose que le fichier a été marqué comme exécutable avec une commande telle que
chmod +x ./file
, qui permet d'invoquer le fichier avec, par exemple,./file
, ou, s'il est situé dans l'un des répertoires listés dans la$PATH
variable, simplement commefile
.- spécifiquement, vous avez besoin d'une ligne shebang pour créer clic basé sur le noeud.js Source files dans le cadre d'un npm package , avec le CLI(s) à être installé par
npm
basé sur la valeur de la touche"bin"
dans le fichierpackage.json
d'un paquet ; voir aussi cette réponse pour savoir comment cela fonctionne avec globalement paquets installés. La note de bas de page [1] montre comment cela est géré sur Windows.
- spécifiquement, vous avez besoin d'une ligne shebang pour créer clic basé sur le noeud.js Source files dans le cadre d'un npm package , avec le CLI(s) à être installé par
-
Vous n'ont PAS besoin de cette ligne pour appeler un fichier explicitement par l'intermédiaire de l'interprète
node
, p.ex.node ./file
Informations générales facultatives :
#!/usr/bin/env <executableName>
est un moyen de de façon portative spécifiant un interpréteur: en un mot, il dit: exécuter <executableName>
partout où vous le trouvez parmi les répertoires listés dans la variable $PATH
(et lui passer implicitement le chemin vers le le fichier à la main).
cela explique le fait qu'un interpréteur donné peut être installé à différents endroits à travers les plateformes, ce qui est certainement le cas avec node
, le noeud.js binaire.
en revanche, l'emplacement de l'utilité env
elle-même peut être considérée comme étant dans le même emplacement à travers les plates - formes, à savoir /usr/bin/env
- et en précisant le complet chemin vers un l'exécutable est requis dans une ligne de shebang.
notez que L'utilitaire POSIX env
est en train d'être réutilisé ici pour localiser par nom de fichier et exécuter un exécutable dans le $PATH
.
Le véritable but de env
est de gérer l'environnement pour une commande-voir env
's POSIX spec et la réponse utile de Keith Thompson .
il est également intéressant de noter ce noeud.js fait une syntaxe exception pour les lignes de shebang, étant donné qu'elles ne sont pas un code JavaScript valide ( #
n'est pas un caractère de commentaire en JavaScript, contrairement aux shells de type POSIX et autres interprètes).
[1] dans l'intérêt de la cohérence entre les plates-formes, npm
crée wrapper *.cmd
fichiers (fichiers par lot) sur Windows lors de l'installation des exécutables spécifiés dans le fichier package.json
d'un paquet (via la propriété "bin"
). Essentiellement, ces fichiers wrapper batch mimic Unix shebang fonctionnalité: ils invoquent le fichier cible explicitement avec l'exécutable spécifié dans la ligne de shebang - ainsi, vos scripts doivent inclure une ligne de shebang même si vous seulement jamais l'intention de les exécuter sur Windows - voir cette réponse de la mienne pour plus de détails.
Étant donné que les fichiers *.cmd
peuvent être invoqués sans l'extension .cmd
, cela permet une expérience multiplateforme sans faille: sous Windows et Unix, vous pouvez effectivement invoquer un CLI npm
-installé par son nom d'origine, sans extension.
qui doivent être exécutés par un interpréteur ont normalement une ligne shebang en haut pour indiquer au système D'exploitation comment les exécuter.
si vous avez un script nommé foo
dont la première ligne est #!/bin/sh
, le système Lira cette première ligne et exécutera l'équivalent de /bin/sh foo
. Pour cette raison, la plupart des interprètes sont configurés pour accepter le nom d'un fichier script comme argument de ligne de commande.
le le nom de l'interpréteur suivant le #!
doit être un chemin complet; L'OS ne cherchera pas votre $PATH
pour trouver l'interpréteur.
si vous avez un script à exécuter par node
, la façon évidente d'écrire la première ligne est:
#!/usr/bin/node
mais cela ne fonctionne pas si la commande node
n'est pas installée dans /usr/bin
.
une solution courante est d'utiliser la commande env
(qui n'était pas vraiment prévu à cet effet):
#!/usr/bin/env node
si votre script s'appelle foo
, L'OS fera l'équivalent de
/usr/bin/env node foo
la commande env
exécute une autre commande dont le nom est indiqué sur sa ligne de commande, en passant tous les arguments suivants à cette commande. La raison pour laquelle il est utilisé ici est que env
va chercher $PATH
pour la commande. Donc si node
est installé dans /usr/local/bin/node
, et vous avez /usr/local/bin
dans votre $PATH
, le commandement env
invoquera /usr/local/bin/node foo
.
le but principal de la commande env
est d'exécuter une autre commande avec un environnement modifié, en ajoutant ou en supprimant des variables d'environnement spécifiées avant d'exécuter la commande. Mais sans arguments supplémentaires, il exécute simplement la commande avec un environnement inchangé, ce qui est tout ce dont vous avez besoin dans ce cas.
Cette approche comporte certains inconvénients. La plupart des systèmes Unix modernes ont /usr/bin/env
, mais j'ai travaillé sur des systèmes plus anciens où la commande env
a été installée dans un répertoire différent. Il pourrait y avoir des limites sur les arguments supplémentaires que vous pouvez passer en utilisant ce mécanisme. Si l'utilisateur n'a pas le répertoire contenant la commande node
dans $PATH
, ou a une autre commande appelée node
, alors il pourrait invoquer la mauvaise commande ou pas de travail du tout.
autres approches:
- utilisez une ligne
#!
qui spécifie le chemin complet vers la commandenode
elle-même, en mettant à jour le script si nécessaire pour différents systèmes; ou - invoquez la commande
node
avec votre script comme argument.
Voir aussi cette question (et ma réponse ) pour plus discussion de la #!/usr/bin/env
truc.
soit dit en passant, sur mon système (Linux Mint 17.2), il est installé comme /usr/bin/nodejs
. Selon mes notes, il a changé de /usr/bin/node
à /usr/bin/nodejs
entre Ubuntu 12.04 et 12.10. Le #!/usr/bin/env
ne vous aidera pas avec cela (à moins que vous mettiez en place un lien symbolique ou quelque chose de similaire).
brève réponse: C'est le chemin vers l'interpréteur.
EDIT (longue réponse): La raison pour laquelle il n'y a pas de slash avant "node" est que vous ne pouvez pas toujours garantir la fiabilité de #!/bac. / Le bit "/ env " rend le programme plus multiplate-forme en exécutant le script dans un environnement modifié et en étant plus fiable pour trouver le programme interprète.
Vous n'avez pas nécessairement besoin, mais il est bon d'utiliser pour assurer la portabilité (et professionalism)