npm 脚本因使用进程替换的命令而失败

npm script fails with commands using process substitutions

运行 我的标准 OSX 终端上的以下内容按预期工作:

$ diff <(ls dir1) <(ls dir2)
correct output here

但是当我尝试 运行 它作为 NPM 脚本时,它失败了:

$ npm run diff
sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `diff <(ls src) <(ls dist)'

当我将 NPM 脚本更改为 "bash -c 'diff <(ls dir1) <(ls dir2)'" 时,它首先输出所需的结果,然后仍然抛出错误(退出状态 1)。

编辑: 顺便说一句,那些奇怪的 <() 符号是 process substitutions。刚了解他们。

尝试

"bash -c 'diff <(ls dir1) <(ls dir2) || exit 0'"

用背景信息补充

来自 https://docs.npmjs.com/misc/scripts:

Scripts are run by passing the line as a script argument to sh.

If the script exits with a code other than 0, then this will abort the process.

具体来说,package.json 文件中的目标 "scripts" 条目的内容作为参数传递给 sh -c,因此与您的命令等效的命令行为:

sh -c 'diff <(ls dir1) <(ls dir2)'

会以同样的方式失败,因为 当 Bash 被调用为 sh 时,设计上它不会识别 process substitutions (<(...)),因为它在 POSIX 兼容模式下运行 .

进程替换 不是 POSIX 的一部分:它们是 Bash -specific 扩展(在 zshksh 中也受支持)。

为了可移植性,您应该只在 "scripts" 条目中使用 POSIX-mandated shell features - 除非您显式调用特定的 shell(如在 Stefan 的回答中),可以直接调用,也可以调用脚本 file,其 shebang 行指定要使用的 shell。

不同的 shell 在不同的平台上充当 sh,您唯一可以依赖的功能是 POSIX.

定义的功能

另外 注意 Stefan 的回答是如何在 Bash 命令末尾使用 || exit 0 的,以确保整个命令始终报告退出代码 0 ,以确保 npm 不会中止处理。