创建一个可移植地指向脚本文件夹中解释器的 shebang

创建一个可移植地指向脚本文件夹中解释器的 shebang

我有一个 JS 文件 ( file.js),我想通过 nodejs (实际上是 iojs )将其作为命令行 shell 脚本执行;我在 Windows 上使用 MINGW Git Bash。

标准方法是将以下 shebang 放入 JS 文件中:

#!/usr/bin/env node

但是,我想将命令行标志传递给节点以激活 V8 和谐功能,即我想要相当于

node --harmony_arrow_functions file.js

当运行时就像

./file.js

无需手动传递标志。

使用

#!/usr/bin/env node --harmony_arrow_functions

不起作用。

考虑后https://stackoverflow.com/a/8108970/245966https://stackoverflow.com/a/5735690/245966我创建了以下解决方案:

$ ls
file.js nodeharmony.sh

$ cat nodeharmony.sh
#!/bin/sh
exec node --harmony_arrow_functions "$@"

$ cat file.js
#!/bin/sh nodeharmony.sh               # or ./nodeharmony.sh, doesn't matter
console.log("Hello world")

$ ./file.js    # this works fine
Hello world

但问题是,当我从另一个文件夹执行它时,shell 尝试nodeharmony.sh在当前工作目录中查找,而不是以下目录file.js

$ cd ..
$ ./subfolder/file.js
/bin/sh: ./nodeharmony.sh: No such file or directory

有没有一种方法可以创建一个便携式 shebang,以便file.js我可以file.js从任何文件夹运行,而无需求助于nodeharmony.sh在 中提供我的自定义解释器 ( ) PATH

编辑:

JS 文件必须保持有效的 JavaScript 文件,因此不能超过初始#!,即当我改变file.js

#!/bin/sh
exec $(dirname $0)/nodeharmony.sh "$0"
console.log("Hello world")

然后 shell 正确传递目录名称和参数,但在 Node 端失败,因为该文件不是有效的 JS 代码:

$ ./subfolder/file.js
d:\CODE\subfolder\file.js:2
exec $(dirname $0)/nodeharmony.sh $0
     ^
SyntaxError: Unexpected identifier
    at exports.runInThisContext (vm.js:54:16)
    ...

编辑2:

我还想保留运行我的脚本的可能性

./file.js

node --harmony_arrow_functions ./file.js

因此,建议对sed文件内容进行黑客攻击,删除标头并将其通过管道传输到 shebang 中的节点,在这种情况下并不好,因为后者的执行将是不可能的。

答案1

编辑:(原始答案仍然回答所述问题,但确实使 file.js 不是有效的 JS 文件)。为了实现所需的行为,接下来的 a将通过跳过前两行来shebang + 1st-line-combination提供 file.js ,从而仅使用 JS 代码来提供它:node

#!/bin/sh
sed '1,2d' $0 |node --harmony_arrow_functions; exit $?
/* Your JS code begins here */

---原答案下方---

如果您可以确定您的解释器将位于解释文件的同一目录中(这是所述问题),您可以使用$(dirname $0)来获取其路径。

例子:

#!/bin/sh
exec $(dirname $0)/nodeharmony.sh "$0" "$@"

在这种情况下,执行时

$ cd ..
$ ./subfolder/file.js

$(dirname $0)解析为./subfolder,因此 exec 将用作./subfolder/nodeharmony.sh解释器。

答案2

您可以生成一个 Node 脚本,它也是一个有效的 shell 脚本来执行此操作:

#!/bin/sh
//usr/bin/env node --harmony_arrow_functions "$0" "$@"; exit $?

console.log("Hello world")

将其另存为file.js会生成一个可以从任何地方运行的脚本。它依赖于//等于/;我还没有在 Windows 上测试过这个...

相关内容