Что именно делает"/usr/bin / env node " в начале файлов узлов?

Я видел эту строку #!/usr/bin/env node в начале некоторых примеров в nodejs и я погуглил, не найдя никакой темы, которая могла бы ответить на причину этой строки.

природа слов делает поиск не так просто.

Я читал некоторые javascript и nodejs книги недавно и я не помню ее ни в одной из них.

если вы хотите пример, вы можете увидеть RabbitMQ официальный учебник, у них почти все вот один из их примеров:--7-->

#!/usr/bin/env node

var amqp = require('amqplib/callback_api');

amqp.connect('amqp://localhost', function(err, conn) {
  conn.createChannel(function(err, ch) {
    var ex = 'logs';
    var msg = process.argv.slice(2).join(' ') || 'Hello World!';

    ch.assertExchange(ex, 'fanout', {durable: false});
    ch.publish(ex, '', new Buffer(msg));
    console.log(" [x] Sent %s", msg);
  });

  setTimeout(function() { conn.close(); process.exit(0) }, 500);
});

может кто-нибудь объяснить мне, что означает эта строка?

какая разница, если я поставлю или удалите эту строку? В каких случаях она мне нужна?

3 ответов


#!/usr/bin/env node is экземпляр shebang line: the самая первая строка в исполняемом текстовом файле на Unix-подобные платформы это говорит системе, какой интерпретатор передать этот файл для выполнения, через командную строку после magic #! префикс (так называемый shebang).

Примечание: Windows тут не поддержка shebang lines, так они эффективно игнорировать там; в Windows это только данный файл расширение это определяет, какой исполняемый файл будет интерпретировать его. однако они все еще нужны вам в контексте npm.[1]

далее, общее обсуждение линий shebang ограничивается Unix-подобными платформами:

в следующем обсуждении я предположу, что файл, содержащий источник код для выполнения узлом.js просто называется file.

  • вы нужна эта строка, если вы хотите вызвать узел.исходный файл js напрямую, как исполняемый файл в своем собственном праве-это предполагает, что файл был помечен как исполняемый с помощью команды, такой как chmod +x ./file, который затем позволяет вызывать файл, например,./file, или, если он находится в одном из каталогов, перечисленных в $PATH переменной, просто as file.

    • в частности, вам нужна линия shebang для создания командная строка на основе узла.исходные файлы js как часть npm пакета, С CLI (s), который будет установлен npm исходя из стоимости "bin" ключ в пакет ; Также см. ответ как это работает установленных пакетов. Сноска [1] показывает, как это осуществляется на Окна.
  • вы не нужны эта строка для вызова файла явно через node переводчик, например, node ./file


дополнительно справочная информация:

#!/usr/bin/env <executableName> путь портативно указание интерпретатора: в двух словах, он говорит: execute <executableName> везде, где вы (первый) найти его среди каталогов, перечисленных в $PATH переменной (и неявно передайте ему путь к файлу под рукой).

это объясняет тот факт, что данный интерпретатор может быть установлен в разных местах на разных платформах, что определенно имеет место с node узел.Яш бинарных.

напротив, местоположение env на саму утилиту можно положиться, чтобы быть в то же самое расположение на разных платформах, а именно /usr/bin/env - и задание полное путь к исполняемому файлу требуются в линии shebang.

обратите внимание, что утилита POSIX env идет переназначены здесь, чтобы найти по имени файла и выполнить исполняемый файл в $PATH.
Истинная цель env для управления средой для команды-см. env'S POSIX spec и полезный ответ кита Томпсона.


также стоит отметить, что узел.JS-это делает синтаксис исключение для строк shebang, учитывая, что они не являются допустимым кодом JavaScript (# не является символом комментария в JavaScript, в отличие от POSIX-подобных оболочек и других интерпретаторов).


[1] в интересах кросс-платформенный последовательности npm создает фантик *.cmd файлы (пакетные файлы) в Windows при установке исполняемых файлов, указанных в пакете (через "bin" свойства). По существу, эти пакетные файлы-оболочки мимические функциональность Unix shebang: они вызовите целевой файл явно с исполняемым файлом, указанным в строке shebang таким образом, ваши скрипты должны включать строку shebang, даже если вы собираетесь запускать их только в Windows - см. ответ шахты для деталей.
С *.cmd файлы могут быть вызваны без


скрипты, которые должны выполняться интерпретатором, обычно имеют shebang line вверху, чтобы рассказать ОС, как их выполнить.

если у вас есть скрипт с именем foo чья первая строка #!/bin/sh, система прочитает эту первую строку и выполнит эквивалент /bin/sh foo. Из-за этого большинство интерпретаторов настроены на принятие имени файла сценария в качестве аргумента командной строки.

имя интерпретатора после #! должен будьте полный путь; ОС не будет искать ваш $PATH, чтобы найти переводчика.

если у вас есть сценарий для выполнения node, очевидный способ написать первую строку:

#!/usr/bin/node

но это не работает, если node команда не установлена в /usr/bin.

общим обходным путем является использование env команда (которая не была действительно предназначенных для этой цели):

#!/usr/bin/env node

если ваш скрипт называется foo, в ОС будет делать эквивалент

/usr/bin/env node foo

на env команда выполняет другую команду, имя которой указано в командной строке, передавая ей любые следующие аргументы. Причина, по которой он используется здесь, заключается в том, что env поиск $PATH для команды. Так что если node установлен в /usr/local/bin/node, а ты /usr/local/bin в своем $PATH на вызывает /usr/local/bin/node foo.

основная цель env команда должна выполнить другую команду с измененной средой добавление или удаление указанных переменных среды перед запуском команды. Но без дополнительных аргументов он просто выполняет команду с неизмененной средой, что все, что вам нужно в этом случае.

в этом подходе есть некоторые недостатки. Большинство современных Unix-подобных систем /usr/bin/env, но я работал над старыми системами, где env команда была установлена в другом каталоге. Могут быть ограничения на дополнительные аргументы вы можете пройти, используя этот механизм. Если пользователь не есть каталог, содержащий на $PATH, или имеет другую команду под названием node, тогда он может вызвать неправильную команду или не работать вообще.

другие подходы:

  • использовать #! строка, указывающая полный путь к node сама команда, обновляющая скрипт по мере необходимости для разных систем; или
  • вызов с вашим сценарием в качестве аргумента.

см. также этот вопросмой ответ:) для более подробного обсуждения #!/usr/bin/env трюк.

кстати, в моей системе (Linux Mint 17.2) он установлен как /usr/bin/nodejs. Согласно моим записям, он изменился с /usr/bin/node to /usr/bin/nodejs между Ubuntu 12.04 и 12.10. The #!/usr/bin/env трюк не поможет с этим (если вы создали символическую ссылку или что-то подобное).


короткий ответ: Это путь к толкователю.

EDIT (длинный ответ): Причина отсутствия косой черты перед "узлом" заключается в том, что вы не всегда можете гарантировать надежность #!/закром. / Бит "/env " делает программу более кросс-платформенной, запуская скрипт в измененной среде и более надежно находя программу интерпретатора.

вам это не обязательно нужно, но хорошо использовать для обеспечения переносимости (и профессионализма)