Skrypty, które mają być wykonane przez tłumacza, zwykle mają linię szarpnięcia u góry która informuje system operacyjny, jak je wykonać.
Jeśli masz skrypt o nazwie, fooktórego pierwsza linia to #!/bin/sh, system odczyta tę pierwszą linię i wykona odpowiednik /bin/sh foo. Z tego powodu większość interpreterów jest skonfigurowana tak, aby akceptować nazwę pliku skryptu jako argument wiersza poleceń.
Nazwa tłumacza występująca po #! musi być pełną ścieżką; system operacyjny nie będzie szukał twojego $PATHtłumacza.
Jeśli masz skrypt do wykonania node, oczywistym sposobem napisania pierwszej linii jest:
#!/usr/bin/node
ale to nie działa, jeśli nodepolecenie nie jest zainstalowane w/usr/bin .
Typowym obejściem jest użycie envpolecenia (które tak naprawdę nie było przeznaczone do tego celu):
#!/usr/bin/env node
Jeśli Twój skrypt zostanie wywołany foo, system operacyjny wykona odpowiednik
/usr/bin/env node foo
envPolecenie wykonuje inną komendę, którego nazwa podana jest w linii poleceń, przechodząc żadnych następujące argumenty do tego polecenia. Powodem jest to, że envwyszuka $PATHpolecenie. Więc jeśli nodejest zainstalowany /usr/local/bin/nodei masz /usr/local/binw swoim $PATH, envpolecenie zostanie wywołane /usr/local/bin/node foo.
Głównym celem envpolecenia jest wykonanie innego polecenia w zmodyfikowanym środowisku, dodanie lub usunięcie określonych zmiennych środowiskowych przed uruchomieniem polecenia. Ale bez dodatkowych argumentów, po prostu wykonuje polecenie w niezmienionym środowisku, co jest wszystkim, czego potrzebujesz w tym przypadku.
Takie podejście ma pewne wady. Większość nowoczesnych systemów typu Unix ma /usr/bin/env, ale pracowałem na starszych systemach, w których envpolecenie zostało zainstalowane w innym katalogu. Mogą istnieć ograniczenia dotyczące dodatkowych argumentów, które można przekazać za pomocą tego mechanizmu. Jeśli użytkownik nie ma katalogu zawierającego nodepolecenie $PATHlub ma inną komendę o nazwienode , może wywołać niewłaściwe polecenie lub w ogóle nie działać.
Inne podejścia to:
- Użyj
#!wiersza określającego pełną ścieżkę do samego nodepolecenia, aktualizując skrypt zgodnie z potrzebami dla różnych systemów; lub
- Wywołaj
nodepolecenie ze swoim skryptem jako argumentem.
Zobacz także to pytanie (i moją odpowiedź ), aby uzyskać więcej informacji na temat#!/usr/bin/env sztuczce.
Nawiasem mówiąc, w moim systemie (Linux Mint 17.2) jest zainstalowany jako /usr/bin/nodejs. Według moich notatek zmieniło się z /usr/bin/nodena /usr/bin/nodejsmiędzy Ubuntu 12.04 a 12.10. Ta #!/usr/bin/envsztuczka nie pomoże w tym (chyba że skonfigurujesz łącze symboliczne lub coś podobnego).
AKTUALIZACJA: komentarz mtraceur mówi (przeformatowano):
Obejście problemu nodejs vs węzeł polega na uruchomieniu pliku z następującymi sześcioma wierszami:
#!/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
*/
To najpierw spróbuje, nodejsa następnie spróbuje nodei wydrukuje komunikaty o błędach tylko wtedy, gdy oba z nich nie zostaną znalezione. Wyjaśnienie jest poza zakresem tych komentarzy, zostawiam je tutaj na wypadek, gdyby pomogło komukolwiek poradzić sobie z problemem, ponieważ ta odpowiedź przyniosła problem.
Ostatnio nie korzystałem z NodeJS. Mam nadzieję, że problem nodejsz nodewersją został rozwiązany w latach, które minęły, odkąd po raz pierwszy opublikowałem tę odpowiedź. W systemie Ubuntu 18.04 nodejspakiet instaluje się /usr/bin/nodejsjako łącze symboliczne do /usr/bin/node. W niektórych wcześniejszych systemach operacyjnych (Ubuntu lub Linux Mint, nie jestem pewien który) istniał nodejs-legacypakiet, który był dostarczany nodejako dowiązanie symboliczne do nodejs. Nie ma gwarancji, że wszystkie szczegóły są prawidłowe.
node