Соответствующий хэшбанг для скриптов Node.js

95

Я пытаюсь создать сценарий для node.js, который будет работать в нескольких средах. В частности, я переключаюсь с OS X на Ubuntu и обратно. В первом случае Node устанавливается как node, а во втором - как nodejs. В верхней части моего сценария я могу иметь:

#!/usr/bin/env node

или

#!/usr/bin/env nodejs

Я бы предпочел, чтобы сценарий запускался как исполняемый файл для любой среды, пока установлен узел, вместо того, чтобы тот или другой должен был указывать команду ( ./script-name.jsvs. node script-name.js).

Есть ли способ указать резервный хэшбэнг или тот, который в любом случае совместим с node.js?

Таблетки от взрыва
источник
вы можете создать сценарий оболочки оболочки для вызова вашего сценария, который пытается выяснить, где находится узел и как он вызывается.
Doon
4
Множество предложений в этом ответе на сайте Unix - unix.stackexchange.com/questions/65235/…
sargant
У меня есть nodejs сценарий , который я изменился от #!/usr/bin/nodeдо , #!/usr/bin/nodejsкогда я модернизировал от Ubuntu 12.04 до 12.10. И он вызывается из оболочки, которая проверяет и то, и другое. Для обсуждения #!/usr/bin/envвзлома см. Этот вопрос и мой ответ .
Кейт Томпсон
1
На этапе 3 есть предложение TC39 под названием «Грамматика хэшбэнга», которое направлено на стандартизацию используемых хэшбэгов: github.com/tc39/proposal-hashbang
M. Twarog

Ответы:

151

Если ваш скрипт предназначен для разработчиков Node, вы должны просто использовать

#!/usr/bin/env node

и не пытайтесь обеспечить совместимость с людьми, у которых Node установлен только как nodejs.

Обоснование:

  • Это то, что делают крутые ребята, и если вы тоже этого не делаете, вы не крутые. Основные узловые проекты , такие как jshint , карма , дача , и даже НПЙ просто использовать #!/usr/bin/env nodeкак притон для своих исполняемых скриптов.
  • Поскольку крутые ребята это делают, любой, кто работает с Node в Ubuntu, создал /usr/bin/nodeсимволическую ссылку на nodejs. Здесь, в Stack Overflow, и во всем Интернете есть хорошо изученные инструкции по выполнению этого. Был даже nodejs-legacyпакет, вся цель которого заключалась в создании для вас этой символической ссылки. Люди, которые используют Node, знают, как решить эту проблему в Ubuntu, и они должны это сделать, если они хотят использовать практически любое программное обеспечение, когда-либо написанное на Node.
  • Проблема, похоже, больше не существует в Ubuntu 14.04; Я просто очистил Node и запустил, apt-get install nodejsи он был создан /usr/bin/nodeкак символическая ссылка на /etc/alternatives/node. Я подозреваю, что людей, страдающих от этой проблемы, становится все меньше и меньше.

Даже если вы нацелены на неграмотных пользователей Node, вы все равно можете захотеть использовать #!/usr/bin/env node, возможно, добавив возможную необходимость создания символических ссылок вручную или установки nodejs-legacyпакета в вашу документацию по установке, если вы сочтете это необходимым. Обратите внимание, что если кто-то, у кого есть доступ, nodejsно nodeнедоступен, попытается запустить вашу программу с указанным выше шебангом, он увидит:

/ usr / bin / env: node: нет такого файла или каталога

и поиск в Google, который даст им исправление в первом результате и много раз на первой странице.

Если вы действительно, отчаянно хотите убедиться, что пользователь может запускать ваше программное обеспечение в системе, где nodejsоно доступно, но nodeне доступно (или где nodeна самом деле находится программа узла любительского пакетного радио ), то вы можете использовать этот "двухстрочный шебанг", взятый из Unix и Linux Stack Exchange :

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

console.log('Hello world!');

но действительно ли вам нужно это делать, когда почти никого в мире узлов нет?

Марк Эмери
источник
2
Если поддержка nodejsисполняемого файла предпочтительнее, вам может показаться немного приятнее использовать shebang с #!/bin/shи //bin/false || exec "$(command -v nodejs || command -v node)" "$0".
lennartcl 02
2
Обратите внимание, что вы не можете передавать аргументы в узел в Linux , например --experimental-modules, если вы используете эту envстроку shebang. Есть хаки, но они уродливые .
Дэн Даскалеску