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é 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é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 $PATH
pour 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 node
commande n'est pas installée dans /usr/bin
.
Une solution de contournement courante consiste à utiliser la env
commande (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 env
commande 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 env
recherchera $PATH
la commande. Donc, si node
est installé dans /usr/local/bin/node
, et que vous avez /usr/local/bin
dans votre $PATH
, la env
commande invoquera /usr/local/bin/node foo
.
L'objectif principal de la env
commande 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 env
commande é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 node
commande 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 node
commande elle-même, en mettant à jour le script selon les besoins pour différents systèmes; ou
- Appelez la
node
commande avec votre script comme argument.
Voir aussi cette question (et ma réponse ) pour plus de discussion sur l' #!/usr/bin/env
astuce.
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/nodejs
entre Ubuntu 12.04 et 12.10. L' #!/usr/bin/env
astuce 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 nodejs
vs node
a été résolu dans les années qui ont suivi la première publication de cette réponse. Sur Ubuntu 18.04, le nodejs
package s'installe en /usr/bin/nodejs
tant 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-legacy
package qui était fourni en node
tant que lien symbolique vers nodejs
. Aucune garantie que j'ai tous les détails.
node