【问题标题】:A sh line that scares me, is it portable?一条吓到我的sh线,便携吗?
【发布时间】:2023-11-10 08:03:01
【问题描述】:

我目前正在开发 NodeJS 的进程管理器 pm2

由于它的目标是 Javascript,一个新的标准即将到来,ES6。 要在 NodeJS 上启用它,我必须添加选项 --harmony

现在对于 bash 部分,我必须让用户将此选项传递给执行文件的解释器。通过爬网(在 * 上找到)我发现了这个:

#!/bin/sh

':' //; exec "`command -v nodejs || command -v node`" $PM2_NODE_OPTIONS "$0" "$@"

bin line

看起来不错,但它是否足够便携?在 CentOS、FreeBSD...

这很关键,所以我想确定一下。

谢谢

【问题讨论】:

    标签: node.js bash sh pm2


    【解决方案1】:

    让我们分解兴趣线。

    : 在 shell 中什么都不做。

    ; 是命令分隔符。

    exec 会将当前进程替换为其正在执行的命令的进程。

    注意到在 exec 命令中它传递了"$0""$@" 作为命令的参数?

    这将允许新进程读取由$0 表示的脚本并将其用作脚本输入并读取原始参数以及$@

    新进程将从头开始读取输入脚本,并忽略 #!/bin/sh 等 cmets。并且也会忽略:

    这就是诀窍。大多数解释器,包括 perl,使用 shell 忽略的语法,反之亦然,因此在重新读取输入文件时,解释器不会再次执行自身。

    在这种情况下,新进程忽略了来自: 的整行。忽略该行的其余部分的原因是什么?在一些类似 c 的解释器上,// 是注释。

    我忘了回答你的问题。是的,它似乎是便携式的。可能有一些极端情况,但我现在想不出。

    【讨论】:

    • 该死的,这是非常聪明的黑客攻击。谢谢你的解释!
    【解决方案2】:

    要在 NodeJS 上启用它,我必须添加选项 --harmony。

    不一定。您可以使用普通的“#!/usr/bin/env node”shebang,但在运行时使用setflags 模块设置和谐标志。

    我不确定这是不是更好的解决方案,但值得一提。

    【讨论】:

    • 不知道这个模块,很高兴知道我的 nodejs 工具箱:D 谢谢!