Les scripts 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é foodont 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éteurs sont configurés pour accepter le nom d'un fichier de script comme argument de ligne de commande.
Le nom de l'interpréteur qui suit #!doit être un chemin complet; le système d'exploitation ne recherchera pas votre $PATHpour trouver l'interprète.
Si vous avez un script à exécuter node, la manière la plus évidente d'écrire la première ligne est:
#!/usr/bin/node
mais cela ne fonctionne pas si la nodecommande n'est pas installée dans /usr/bin.
Une solution de contournement courante consiste à utiliser la envcommande (qui n'était pas vraiment destinée à cet effet):
#!/usr/bin/env node
Si votre script est appelé foo, le système d'exploitation fera l'équivalent de
/usr/bin/env node foo
La envcommande exécute une autre commande dont le nom est donné sur sa ligne de commande, en passant les arguments suivants à cette commande. La raison pour laquelle il est utilisé ici est qu'il envrecherchera $PATHla commande. Donc, si nodeest installé dans /usr/local/bin/node, et que vous avez /usr/local/bindans votre $PATH, la envcommande invoquera /usr/local/bin/node foo.
L'objectif principal de la envcommande 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 dont vous avez besoin dans ce cas.
Cette approche présente certains inconvénients. La plupart des systèmes modernes de type Unix l'ont fait /usr/bin/env, mais j'ai travaillé sur des systèmes plus anciens où la envcommande était installée dans un répertoire différent. Il peut y avoir des limitations sur les arguments supplémentaires que vous pouvez transmettre à l'aide de ce mécanisme. Si l'utilisateur n'a pas le répertoire contenant la nodecommande dans $PATH, ou si une commande différente est appelée node, alors il pourrait appeler la mauvaise commande ou ne pas fonctionner du tout.
D'autres approches sont:
- Utilisez une
#!ligne qui spécifie le chemin complet de la nodecommande elle-même, en mettant à jour le script selon les besoins pour différents systèmes; ou
- Appelez la
nodecommande avec votre script comme argument.
Voir aussi cette question (et ma réponse ) pour plus de discussion sur l' #!/usr/bin/envastuce.
Incidemment, sur mon système (Linux Mint 17.2), il est installé en tant que /usr/bin/nodejs. Selon mes notes, il est passé de /usr/bin/nodeà /usr/bin/nodejsentre Ubuntu 12.04 et 12.10. L' #!/usr/bin/envastuce n'aidera pas avec cela (à moins que vous ne configuriez un lien symbolique ou quelque chose de similaire).
MISE À JOUR: Un commentaire de mtraceur dit (reformaté):
Une solution de contournement pour le problème nodejs vs node consiste à démarrer le fichier avec les six lignes suivantes:
#!/bin/sh -
':' /*-
test1=$(nodejs --version 2>&1) && exec nodejs "$0" "$@"
test2=$(node --version 2>&1) && exec node "$0" "$@"
exec printf '%s\n' "$test1" "$test2" 1>&2
*/
Cela essaiera d'abord nodejs, puis essaiera node, et n'imprimera les messages d'erreur que si les deux ne sont pas trouvés. Une explication est hors de portée de ces commentaires, je la laisse juste ici au cas où cela aiderait quiconque à résoudre le problème puisque cette réponse a soulevé le problème.
Je n'ai pas utilisé NodeJS récemment. J'espère que le problème du nodejsvs nodea été résolu dans les années qui ont suivi la première publication de cette réponse. Sur Ubuntu 18.04, le nodejspackage s'installe en /usr/bin/nodejstant que lien symbolique vers /usr/bin/node. Sur certains systèmes d'exploitation antérieurs (Ubuntu ou Linux Mint, je ne sais pas lequel), il y avait un nodejs-legacypackage qui était fourni en nodetant que lien symbolique vers nodejs. Aucune garantie que j'ai tous les détails.
node