Skripte, die von einem Interpreter ausgeführt werden sollen, haben normalerweise eine Shebang-Zeile oben, um dem Betriebssystem mitzuteilen, wie sie ausgeführt werden sollen.
Wenn Sie ein Skript mit dem Namen haben, foodessen erste Zeile lautet #!/bin/sh, liest das System diese erste Zeile und führt das Äquivalent von aus /bin/sh foo. Aus diesem Grund sind die meisten Interpreter so eingerichtet, dass sie den Namen einer Skriptdatei als Befehlszeilenargument akzeptieren.
Der Name des Interpreters #!nach muss ein vollständiger Pfad sein. Das Betriebssystem sucht nicht $PATHnach dem Interpreter.
Wenn Sie ein Skript haben, das ausgeführt werden soll node, können Sie die erste Zeile auf folgende Weise schreiben:
#!/usr/bin/node
Das funktioniert aber nicht, wenn der nodeBefehl nicht installiert ist /usr/bin.
Eine übliche Problemumgehung besteht darin, den envBefehl zu verwenden (der nicht wirklich für diesen Zweck vorgesehen war):
#!/usr/bin/env node
Wenn Ihr Skript aufgerufen wird foo, führt das Betriebssystem das Äquivalent von aus
/usr/bin/env node foo
Der envBefehl führt einen anderen Befehl aus, dessen Name in der Befehlszeile angegeben ist, und übergibt alle folgenden Argumente an diesen Befehl. Der Grund, warum es hier verwendet wird, ist, dass envnach $PATHdem Befehl gesucht wird . Wenn nodealso in installiert /usr/local/bin/nodeist und Sie /usr/local/binin Ihrem haben $PATH, wird der envBefehl aufgerufen /usr/local/bin/node foo.
Der Hauptzweck des envBefehls besteht darin, einen anderen Befehl mit einer geänderten Umgebung auszuführen und bestimmte Umgebungsvariablen hinzuzufügen oder zu entfernen, bevor der Befehl ausgeführt wird. Ohne zusätzliche Argumente wird der Befehl jedoch nur in einer unveränderten Umgebung ausgeführt, was in diesem Fall alles ist, was Sie benötigen.
Dieser Ansatz weist einige Nachteile auf. Die meisten modernen Unix-ähnlichen Systeme haben /usr/bin/env, aber ich habe auf älteren Systemen gearbeitet, auf denen der envBefehl in einem anderen Verzeichnis installiert wurde. Möglicherweise gibt es Einschränkungen für zusätzliche Argumente, die Sie mit diesem Mechanismus übergeben können. Wenn der Benutzer nicht das das Verzeichnis enthalten , haben nodeBefehl in $PATH, oder hat einige andere Befehl aufgerufen node, dann könnte es das falsche Kommando oder keine Arbeit überhaupt aufrufen.
Andere Ansätze sind:
- Verwenden Sie eine
#!Zeile, die den vollständigen Pfad zum nodeBefehl selbst angibt , und aktualisieren Sie das Skript nach Bedarf für verschiedene Systeme. oder
- Rufen Sie den
nodeBefehl mit Ihrem Skript als Argument auf.
Siehe auch diese Frage (und meine Antwort ) für weitere Diskussionen über den #!/usr/bin/envTrick.
Auf meinem System (Linux Mint 17.2) ist es übrigens installiert als /usr/bin/nodejs. Nach meinen Notizen, änderte sie sich von /usr/bin/nodezu /usr/bin/nodejszwischen Ubuntu 12.04 und 12.10. Der #!/usr/bin/envTrick hilft dabei nicht (es sei denn, Sie richten einen Symlink oder ähnliches ein).
UPDATE: Ein Kommentar von mtraceur sagt (neu formatiert):
Eine Problemumgehung für das Problem nodejs vs node besteht darin, die Datei mit den folgenden sechs Zeilen zu starten:
#!/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
*/
Dies wird zuerst versuchen nodejsund dann versuchen nodeund die Fehlermeldungen nur drucken, wenn beide nicht gefunden werden. Eine Erklärung liegt außerhalb des Rahmens dieser Kommentare. Ich lasse sie nur hier, falls sie jemandem hilft, mit dem Problem umzugehen, da diese Antwort das Problem angesprochen hat.
Ich habe NodeJS in letzter Zeit nicht verwendet. Ich hoffe, dass das Problem nodejsvs. nodein den Jahren, seit ich diese Antwort zum ersten Mal gepostet habe, behoben wurde. Unter Ubuntu 18.04 wird das nodejsPaket /usr/bin/nodejsals Symlink zu installiert /usr/bin/node. Auf einigen früheren Betriebssystemen (Ubuntu oder Linux Mint, ich bin mir nicht sicher, welches) gab es ein nodejs-legacyPaket, das nodeals Symlink zu bereitgestellt wurde nodejs. Keine Garantie, dass ich alle Details richtig habe.
node