Node.js ist heutzutage sehr beliebt und ich habe einige Skripte darüber geschrieben. Leider ist die Kompatibilität ein Problem. Offiziell sollte der Node.js-Interpreter aufgerufen werden node
, aber Debian und Ubuntu liefern nodejs
stattdessen eine ausführbare Datei namens .
Ich möchte portable Skripte, mit denen Node.js in möglichst vielen Situationen arbeiten kann. Angenommen, der Dateiname lautet " foo.js
Ich möchte wirklich, dass das Skript auf zwei Arten ausgeführt wird:
./foo.js
Führt das Skript aus, wenn entwedernode
oder vorhandennodejs
ist$PATH
.node foo.js
führt auch das Skript aus (vorausgesetzt, der Interpreter wird aufgerufennode
)
Hinweis: Die Antworten von xavierm02 und mir sind zwei Variationen eines mehrsprachigen Skripts. Ich bin immer noch an einer reinen Shebang-Lösung interessiert, falls es eine gibt.
scripting
compatibility
node.js
dancek
quelle
quelle
node
für Ihr Skript zu verwenden oder eine Art make-Skript zu verwenden, das den shebang modifiziert.alphacentauri
und so weiter unterstützen. Wenn eine ausführbare Datei aufgerufen wirdnodejs
, können Sie zu 99% sicher sein, dass es sich um Node.js handelt. Warum nicht beidenodejs
und unterstützennode
?Antworten:
Das Beste, was ich mir ausgedacht habe, ist dieses "Two-Line-Shebang", das wirklich ein vielsprachiges Skript (Bourne-Shell / Node.js) ist:
Die erste Zeile ist offensichtlich ein Bourne-Shell-Shebang. Node.js umgeht jeden gefundenen Schebang. Für Node.js handelt es sich also um eine gültige Javascript-Datei.
Die zweite Zeile ruft die Shell no-op
:
mit dem Argument auf//
und führt dannnodejs
odernode
mit dem Namen dieser Datei als Parameter aus.command -v
wird anstelle vonwhich
für die Portabilität verwendet. Die Befehlssubstitutionssyntax$(...)
ist nicht ausschließlich Bourne, entscheiden Sie sich also für Backticks, wenn Sie diese in den 1980er Jahren ausführen.Node.js wertet nur den String aus
':'
, der wie ein No-Op ist, und der Rest der Zeile wird als Kommentar analysiert.Der Rest der Datei ist einfach altes Javascript. Die Subshell wird nach Abschluss der
exec
zweiten Zeile beendet, sodass der Rest der Datei nie von der Shell gelesen wird.Vielen Dank an xavierm02 für die Inspiration und alle Kommentatoren für zusätzliche Informationen!
quelle
':'
Ansatz ist die Verwendung// 2>/dev/null
(was auch immer dernvm
Fall ist): Beim Bash ist es ein Fehler (bash: //: Is a directory
), den die Umleitung im2>/dev/null
Hintergrund ignoriert. Für JavaScript wird die gesamte Zeile zu einem Kommentar. Außerdem - und ich erwarte nicht, dass dies ein Problem für IRL ist -command
gibt es eine Besonderheit, bei der auch Shell-Funktionen und Aliase mit gemeldet werden-v
- auch wenn sie nicht tatsächlich aufgerufen werden. Wenn Sie also zufällig Shell-Funktionen oder sogar Aliase (vorausgesetztshopt -s expand_aliases
) mit dem Namennode
oder exportiert haben, kann dies zu Problemen führennodejs
.mksh
,bash
,dash
und andere Shells in modernen Unix und GNU - Systemen.#!/usr/bin/env sh
anstatt#!/bin/sh
(per en.wikipedia.org/wiki/Shebang_%28Unix%29#Portability )#!/usr/bin/env sh
als "portabler" vorsichtig sein . Das gleiche Wikipedia - Artikel sagt : „Das funktioniert vor allem , weil der Pfad / usr / bin / env gemeinsam für das env - Dienstprogramm verwendet wird ...“ Das ist nicht eine wunderbare Bestätigung, und meine Vermutung ist , dass Sie in die Systeme laufen werden , ohne/usr/bin/env
häufiger als Sie stoßen auf Systeme ohne/bin/sh
, wenn es überhaupt Unterschiede in der Frequenz gibt.//bin/sh -c :; exec ...
eine sauberere Version der zweiten Zeile nicht?//bin/false
ist das Gleiche wie mit der/bin/false
Ausnahme, dass der zweite Schrägstrich ihn in einen Kommentar für node umwandelt, und deshalb ist er hier. Dann wird die rechte Seite der ersten||
ausgewertet.'which node || which nodejs'
Mit Anführungszeichen anstelle von Anführungszeichen wird der Knoten gestartet und der<<
Feed wird angezeigt, was auch immer auf der rechten Seite ist. Ich hätte ein Trennzeichen verwenden können, das//
wie Dancek anfängt. Es hätte funktioniert, aber ich finde, dass es sauberer ist, wenn am Anfang nur zwei Zeilen stehen. Daher habe ichtail -n +2 $0
die Datei bis auf die ersten beiden Zeilen selbst gelesen.Wenn Sie es in node ausführen, wird die erste Zeile als "shebang" erkannt und ignoriert, und die zweite Zeile ist ein einzeiliger Kommentar.
(Anscheinend könnte sed verwendet werden, um den Inhalt der Tail Print-Datei ohne die erste und letzte Zeile zu ersetzen. )
Antwort vor dem Bearbeiten:
Sie können nicht tun, was Sie wollen. Stattdessen führen Sie ein Shell-Skript aus
#!/bin/sh
. Dieses Shell-Skript erhält den Pfad der Datei, die zum Ausführen des Knotens benötigt wirdwhich node || which nodejs
. Die Backquotes sind hier, damit es ausgeführt wird, also'which node || which nodejs'
ruft (mit den Backquotes anstelle der Quotes) einfach node auf. Dann füttern Sie einfach Ihr Skript damit<<
. Das__HERE__
sind die Begrenzer Ihres Skripts. Und dasconsole.log('ok');
ist ein Beispiel für ein Skript, das Sie durch Ihr Skript ersetzen sollten.quelle
<<'__HERE__'
.//bin/false
es in meiner MSYS-Umgebung nicht funktioniert und ich Anführungszeichen für die Backticks benötige, da ich beinode
wohntC:\Program Files\...
. Ja, ich arbeite in einer schrecklichen Umgebung ...//bin/false
funktioniert auch unter Mac OS X nicht. Es tut mir leid, aber das scheint nicht mehr tragbar zu sein.which
Befehl ist auch nicht portierbar.Dies ist nur ein Problem auf Debian-basierten Systemen, bei denen die Richtlinien den Sinn überstiegen.
Ich weiß nicht, wann Fedora eine Binärdatei namens nodejs bereitgestellt hat, aber ich habe sie nie gesehen. Das Paket heißt nodejs und installiert eine Binärdatei namens node.
Verwenden Sie einfach einen Symlink, um gesunden Menschenverstand auf Ihre Debian-basierten Systeme anzuwenden, und dann können Sie einen vernünftigen Schebang verwenden. Andere Leute werden sowieso vernünftige Scheiße benutzen, also wirst du diesen Symlink brauchen.
quelle
nodejs
ausführbar , aber das ist nicht Fedora Schuld. Entschuldigung für die falsche Darstellung der Tatsache.#!/usr/bin/perl
. Das heißt, Sie sind nicht verpflichtet, meine Vorschläge zu mögen oder anzuwenden. Frieden.Wenn es Ihnen nichts ausmacht, eine kleine
.sh
Datei zu erstellen, habe ich eine kleine Lösung für Sie. Sie können ein kleines Shell-Skript erstellen, um zu bestimmen, welche Knoten-Programmdatei verwendet werden soll, und dieses Skript in Ihrem shebang verwenden:shebang.sh :
script.js :
Markieren Sie beide ausführbaren Dateien und führen Sie sie aus
./script.js
.Auf diese Weise vermeiden Sie mehrsprachiges Scripting. Ich denke nicht, dass die Verwendung mehrerer Shebang-Linien möglich ist, obwohl dies eine gute Idee zu sein scheint.
Obwohl dies das Problem auf die von Ihnen gewünschte Weise löst, scheint es, dass sich niemand darum kümmert. Zum Beispiel uglifyjs und Coffeescript Anwendungen
#!/usr/bin/env node
, npm verwendet einen Shell - Skript als Einstiegspunkt, der wiederum die ausführbare Datei mit dem Namen explizit aufruftnode
. Ich bin ein Ubuntu-Benutzer und wusste das nicht, da ich den Knoten immer kompiliere. Ich denke darüber nach, dies als Fehler zu melden.quelle
chmod +x
chmod +x
'd freigeben . Und ich stimme zu, dass eine NODE-Variable besser ist alswhich node || which nodejs
. Der Anfragende möchte jedoch eine sofort einsatzbereite Erfahrung bieten, obwohl viele große Knotenprojekte nur diese verwenden#!/usr/bin/env node
.Der Vollständigkeit halber gibt es hier ein paar andere Möglichkeiten, die zweite Zeile zu machen:
Beides hat aber keinen Vorteil gegenüber der gewählten Antwort:
Wenn Sie wüssten, dass entweder
node
odernodejs
(aber nicht beide) gefunden werden, funktioniert Folgendes:Aber das ist ein großes "Wenn", daher denke ich, dass die ausgewählte Antwort die beste bleibt.
quelle
foobar // 2>/dev/null
solange erfoobar
kein Befehl ist. Und viele der auf jedem POSIX-System gefundenen Dienstprogramme können mit diesem//
Argument ausgeführt werden.Ich verstehe, dass dies die Frage nicht beantwortet, aber ich bin überzeugt, dass die Frage mit einer falschen Prämisse gestellt wird.
Ubuntu ist hier falsch. Das Schreiben eines universellen Shebangs für Ihr eigenes Skript ändert nichts an anderen Paketen, über die Sie keine Kontrolle haben und die den De-facto-Standard von verwenden
#!/usr/bin/env node
. Ihr System muss liefernnode
in ,PATH
wenn es für alle Skripte wünscht NodeJS Targeting darauf laufen.Beispielsweise
npm
schreibt nicht einmal das von Ubuntu bereitgestellte Paket Shebangs in Pakete um:quelle