Geeigneter Hashbang für Node.js-Skripte

91

Ich versuche, ein Skript für node.js zu erstellen, das in mehreren Umgebungen funktioniert. Besonders für mich wechsle ich zwischen OS X und Ubuntu hin und her. Im ersten Fall wird Node als installiert node, im zweiten Fall jedochnodejs . Am Anfang meines Skripts kann ich Folgendes haben:

#!/usr/bin/env node

oder

#!/usr/bin/env nodejs

Ich möchte lieber, dass das Skript als ausführbare Datei für eine der beiden Umgebungen ausgeführt wird, solange der Knoten installiert ist, anstatt dass der eine oder andere den Befehl ( ./script-name.jsvs. node script-name.js) angeben muss .

Gibt es eine Möglichkeit, einen Backup-Hashbang anzugeben oder einen, der in beiden Fällen für node.js kompatibel ist?

Explosionspillen
quelle
Sie könnten ein Wrapper-Shell-Skript erstellen, um Ihr Skript aufzurufen, das versucht herauszufinden, wo der Knoten lebt und wie er heißt.
Doon
4
Viele Vorschläge in dieser Antwort auf der Unix-Site - unix.stackexchange.com/questions/65235/…
sargant
Ich habe ein NodeJS-Skript, von #!/usr/bin/nodedem #!/usr/bin/nodejsich beim Upgrade von Ubuntu 12.04 auf 12.10 geändert habe . Und es wird von einem Wrapper aufgerufen, der nach beiden sucht. Zur Diskussion des #!/usr/bin/envHacks siehe diese Frage und meine Antwort .
Keith Thompson
Es gibt einen TC39-Vorschlag in Stufe 3 mit dem Namen "Hashbang-Grammatik", der darauf abzielt, verwendete Hashbangs zu standardisieren: github.com/tc39/proposal-hashbang
M. Twarog

Antworten:

144

Wenn Ihr Skript für die Verwendung durch Node-Entwickler vorgesehen ist, sollten Sie es unbedingt nur verwenden

#!/usr/bin/env node

und nicht versuchen, Kompatibilität mit Leuten zu versuchen, die nur Node als installiert haben nodejs.

Begründung:

  • Es ist das, was die coolen Kids machen, und wenn du es nicht auch machst, bist du nicht cool. Große Knotenprojekte wie jshint , karma , bower und sogar npm werden einfach #!/usr/bin/env nodeals Shebang für ihre ausführbaren Skripte verwendet.
  • Weil die coolen Kids es tun, hat jeder, der mit Node unter Ubuntu arbeitet, einen /usr/bin/nodeals Symlink zu eingerichtet nodejs. Hier auf Stack Overflow und im gesamten Web finden Sie häufig angezeigte Anweisungen dazu . Es gab sogar das nodejs-legacyPaket, dessen gesamter Zweck darin bestand, diesen Symlink für Sie zu erstellen. Leute, die Node verwenden, wissen, wie man dieses Problem unter Ubuntu behebt, und sie müssen, wenn sie so ziemlich jede Software verwenden wollen, die jemals in Node geschrieben wurde.
  • Das Problem scheint unter Ubuntu 14.04 nicht mehr zu existieren. Ich habe gerade Node gelöscht und ein ausgeführt apt-get install nodejsund es wurde /usr/bin/nodeals Symlink zu erstellt /etc/alternatives/node. Ich vermute, die von diesem Problem betroffenen Menschen sind eine schrumpfende Minderheit.

Selbst wenn Sie sich an Node-Analphabeten wenden, möchten Sie diese möglicherweise weiterhin verwenden #!/usr/bin/env nodeund möglicherweise die Notwendigkeit einer manuellen Symlink-Erstellung oder Installation des nodejs-legacyPakets zu Ihrer Installationsdokumentation hinzufügen, wenn Sie dies für erforderlich halten. Beachten Sie, dass jemand mit nodejs, der nicht nodeverfügbar ist und versucht, Ihr Programm mit dem oben genannten Shebang auszuführen, Folgendes sieht:

/ usr / bin / env: node: Keine solche Datei oder kein solches Verzeichnis

und Googeln, das ihnen die Korrektur im ersten Ergebnis und viele Male auf der ersten Seite gibt.

Wenn Sie wirklich unbedingt sicherstellen möchten, dass der Benutzer Ihre Software auf einem System ausführen kann, auf dem nodejsverfügbar ist, das jedoch nodenicht verfügbar ist (oder auf dem nodesich tatsächlich das Amateur Packet Radio Node-Programm befindet ), können Sie diesen "zweizeiligen Shebang" verwenden von Unix & Linux Stack Exchange :

#!/bin/sh
':' //; exec "$(command -v nodejs || command -v node)" "$0" "$@"

console.log('Hello world!');

Aber müssen Sie das wirklich tun, wenn es fast niemand in der Knotenwelt gibt?

Mark Amery
quelle
2
Wenn die Unterstützung für die nodejsausführbare Datei bevorzugt wird, ist es möglicherweise etwas hübscher, einen Shebang mit #!/bin/shund zu verwenden //bin/false || exec "$(command -v nodejs || command -v node)" "$0".
Lennartcl
2
Beachten Sie, dass Sie unter Linux keine Argumente an Node übergeben können , z. B. --experimental-moduleswenn Sie diese envShebang-Zeile verwenden. Es gibt Hacks, aber sie sind hässlich .
Dan Dascalescu