Gli script che devono essere eseguiti da un interprete normalmente hanno una linea shebang in alto per dire al sistema operativo come eseguirli.
Se hai uno script chiamato la foocui prima riga è #!/bin/sh, il sistema leggerà quella prima riga ed eseguirà l'equivalente di /bin/sh foo. Per questo motivo, la maggior parte degli interpreti è configurata per accettare il nome di un file di script come argomento della riga di comando.
Il nome dell'interprete che segue #!deve essere un percorso completo; il sistema operativo non cercherà il tuo $PATHper trovare l'interprete.
Se hai uno script da eseguire node, il modo più ovvio per scrivere la prima riga è:
#!/usr/bin/node
ma non funziona se il nodecomando non è installato in /usr/bin.
Una soluzione alternativa comune consiste nell'usare il envcomando (che non era realmente destinato a questo scopo):
#!/usr/bin/env node
Se lo script viene chiamato foo, il sistema operativo eseguirà l'equivalente di
/usr/bin/env node foo
Il envcomando esegue un altro comando il cui nome è dato sulla sua riga di comando, passando i seguenti argomenti a quel comando. Il motivo per cui viene utilizzato qui è che envcercherà $PATHil comando. Quindi, se nodeè installato in /usr/local/bin/node, e lo hai /usr/local/binnel tuo $PATH, il envcomando verrà richiamato /usr/local/bin/node foo.
Lo scopo principale del envcomando è eseguire un altro comando con un ambiente modificato, aggiungendo o rimuovendo le variabili di ambiente specificate prima di eseguire il comando. Ma senza argomenti aggiuntivi, esegue semplicemente il comando con un ambiente invariato, che è tutto ciò di cui hai bisogno in questo caso.
Ci sono alcuni svantaggi in questo approccio. La maggior parte dei moderni sistemi Unix lo hanno /usr/bin/env, ma ho lavorato su sistemi più vecchi in cui il envcomando era installato in una directory diversa. Potrebbero esserci limitazioni su argomenti aggiuntivi che puoi passare usando questo meccanismo. Se l'utente non ha la directory contenente il nodecomando $PATHo ha chiamato un comando diverso node, potrebbe richiamare il comando sbagliato o non funzionare affatto.
Altri approcci sono:
- Utilizzare una
#!riga che specifica il percorso completo del nodecomando stesso, aggiornando lo script secondo necessità per i diversi sistemi; o
- Invoca il
nodecomando con il tuo script come argomento.
Vedi anche questa domanda (e la mia risposta ) per ulteriori discussioni sul #!/usr/bin/envtrucco.
Per inciso, sul mio sistema (Linux Mint 17.2), è installato come /usr/bin/nodejs. Secondo le mie note, è cambiato da /usr/bin/nodea /usr/bin/nodejstra Ubuntu 12.04 e 12.10. Il #!/usr/bin/envtrucco non aiuta in questo (a meno che tu non abbia impostato un collegamento simbolico o qualcosa di simile).
AGGIORNAMENTO: Un commento di mtraceur dice (riformattato):
Una soluzione alternativa per il problema nodejs vs node è avviare il file con le seguenti sei righe:
#!/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
*/
Questo proverà prima nodejse poi proverà nodee stamperà i messaggi di errore solo se non vengono trovati entrambi. Una spiegazione esula dallo scopo di questi commenti, la lascio qui nel caso in cui aiuti qualcuno ad affrontare il problema poiché questa risposta ha sollevato il problema.
Non ho usato NodeJS ultimamente. La mia speranza è che il problema nodejsvs. nodesia stato risolto negli anni trascorsi da quando ho pubblicato questa risposta per la prima volta. Su Ubuntu 18.04, il nodejspacchetto viene installato /usr/bin/nodejscome collegamento simbolico a /usr/bin/node. Su alcuni sistemi operativi precedenti (Ubuntu o Linux Mint, non sono sicuro di quale), c'era un nodejs-legacypacchetto che forniva nodeun collegamento simbolico a nodejs. Nessuna garanzia di avere tutti i dettagli corretti.
node