“/ usr / bin / env节点”到底在节点文件的开始处做了什么?
我曾经在nodejs的一些例子的开头看过这行#!/usr/bin/env node ,并且我没有find可以回答该行的原因的任何主题。 
单词的性质使得search不那么容易。
 我最近读了一些javascript和nodejs书,我不记得在其中任何一本。 
 如果你想要一个例子,你可以看到RabbitMQ官方教程 ,几乎所有的例子都有它,下面是其中的一个例子: 
 #!/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); }); 
有人能解释一下这条线的含义吗?
如果我放置或删除此行,有什么区别? 在什么情况下我需要它?
  #!/usr/bin/env node是shebang行的一个实例 : 类Unix平台上的可执行纯文本文件中的第一行,告诉系统通过命令传递该文件以执行的解释器线以下魔术#! 前缀(称为shebang )。 
 注意: Windows不支持shebang行 ,所以它们在那里被有效地忽略 ; 在Windows上,它只是一个给定文件的文件扩展名 ,它决定了可执行文件将解释它。  但是,你仍然需要在npm的情况下 。  [1] 
以下关于shebang行的一般性讨论仅限于Unix类平台:
  在下面的讨论中,我假定包含由Node.js执行的源代码的文件是简单的命名file 。 
- 
你需要这一行 ,如果你想直接调用一个Node.js源文件,作为一个可执行文件 – 它假设文件已经被标记为可执行文件,如 chmod +x ./file,然后允许你使用例如./file调用该文件,或者如果它位于$PATHvariables中列出的目录之一中,则简单地作为file。-  具体来说,您需要一个shebang行来创build基于Node.js源文件的CLI作为npm 包的一部分,CLI将根据包的package.json"bin"键的值通过npm进行安装package.json文件 ; 也看到这个答案如何与全球安装的软件包一起工作。 脚注[1]显示了如何在Windows上处理这个问题。
 
-  具体来说,您需要一个shebang行来创build基于Node.js源文件的CLI作为npm 包的一部分,CLI将根据包的
- 
您不需要通过 node解释器显式调用文件,例如node ./file
可选的背景信息 :
  #!/usr/bin/env <executableName>是一种可移植指定解释器的方法:简而言之,它说:execute <executableName>无论你在哪里(首先)在$PATHvariables列出的目录中find它把它传递给手头文件的path)。 
这说明了一个给定的解释器可以跨平台安装在不同的位置,Node.js二进制文件就是这种情况。
 相比之下, env实用程序本身的位置可以依赖于跨平台的相同位置,即/usr/bin/env ,并且在shebang行中指定可执行文件的完整path。 
 请注意,POSIX实用程序env被重新用于此处,以按文件名进行定位并在$PATH执行一个可执行文件。 
  env的真正目的是pipe理一个命令的环境 – 请参阅env的POSIX规范和Keith Thompson的有用答案 。 
 同样值得注意的是,Node.js为shebang行创build了一个语法exception ,因为它们不是有效的JavaScript代码( #不像JavaScript中的注释字符,不像POSIX类的shell和其他解释器)。 
  [1]为了实现跨平台一致性, npm在安装程序包的package.json文件中指定的可执行文件(通过"bin"属性)时在Windows上创buildwrapper *.cmd文件(batch file )。  实质上,这些包装batch file模仿 Unix shebangfunction:它们用shebang行中指定的可执行文件显式地调用目标文件 – 因此, 即使您只是打算在Windows上运行它们 , 您的脚本也必须包含shebang行 – 请参阅此答案我的细节。 
  由于*.cmd文件可以在没有.cmd扩展名的情况下被调用,因此可以获得无缝的跨平台体验:在Windows和Unix上,您可以通过原始的扩展名来有效地调用npm installed CLI。 
由解释器执行的脚本通常在顶部有一个shebang行 ,告诉操作系统如何执行它们。
 如果您有一个名为foo的脚本,其第一行是#!/bin/sh ,系统将读取第一行并执行相应的/bin/sh foo 。 因此,大多数解释器被设置为接受脚本文件的名称作为命令行参数。 
 在#!之后的解释器名称#! 必须是一个完整的path; 操作系统将不会search您的$PATHfind解释器。 
 如果你有一个脚本被node执行,写第一行的方法是: 
 #!/usr/bin/node 
 但是如果node命令没有安装在/usr/bin ,那不起作用。 
 一个常见的解决方法是使用env命令(这并不是真正用于此目的): 
 #!/usr/bin/env node 
 如果您的脚本被称为foo ,则操作系统将执行相同的操作 
 /usr/bin/env node foo 
  env命令会执行另一个在其命令行上给出名称的命令,并将任何以下parameter passing给该命令。 这里使用的原因是env会search$PATH作为命令。 因此,如果node安装在/usr/local/bin/node ,并且在$PATH有/usr/local/bin ,则env命令将调用/usr/local/bin/node foo 。 
  env命令的主要目的是在修改后的环境中执行另一个命令,在运行该命令之前添加或删除指定的环境variables。 但是没有额外的参数,它只是在一个没有改变的环境下执行这个命令,在这种情况下就是你所需要的。 
 这种方法有一些缺点。 大多数现代类Unix系统都有/usr/bin/env ,但我曾经在较旧的系统上安装过env命令安装在不同的目录中。 使用这种机制可能会传递额外的参数。 如果用户在$PATH 中没有包含node命令的目录,或者有一些不同的命令叫做node ,那么它可能会调用错误的命令或者根本不工作。 
其他方法是:
-  使用#!该行指定node命令本身的完整path,根据需要更新不同系统的脚本; 要么
-  用脚本调用node命令作为参数。
 有关#!/usr/bin/env技巧的更多讨论,另请参阅此问题 (和我的回答 )。 
 顺便说一下,在我的系统(Linux Mint 17.2)上,它被安装为/usr/bin/nodejs 。 根据我的说明,它在Ubuntu 12.04和12.10之间从/usr/bin/node更改为/usr/bin/nodejs 。  #!/usr/bin/env技巧对此没有帮助(除非你设置了一个符号链接或类似的东西)。 
简短的回答:这是翻译的道路。
编辑(长答):在“节点”之前没有斜线的原因是因为你不能总是保证#!/ bin /的可靠性。 “/ env”位通过在修改的环境中运行脚本并更可靠地find解释程序,使程序更具跨平台性。
你不一定需要它,但是确保可移植性(和专业性)