npm脚本使用进程replace命令失败

在我的标准OSXterminal上运行以下操作按预期工作:

$ 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)。

编辑:这些怪异的<()符号是过程replace的方式。 刚刚了解了他们。

为了补充Stefan Hegny的有用答案和背景资料:

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

脚本通过将行作为脚本parameter passing给sh

如果脚本以非0的代码退出,则会中止该过程。

具体来说, package.json文件中的目标"scripts"条目的内容作为parameter passing给sh -c ,因此命令行等同于您的命令:

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

这将以相同的方式失败,因为当Bash被调用为sh ,由于它在POSIX兼容模式下运行,因此它不能识别进程replace ( <(...)

进程replace不是 POSIX的一部分 :它们是Bash特定的扩展(也支持zshksh )。

为了可移植性,除非你直接调用特定的shell (如Stefan的答案),或者通过调用一个脚本文件 ,该文件的shebang行指定了shell,以便在你的"scripts"条目中只能使用POSIX授权的shell特性使用。

不同的shell在不同的平台上运行,你可以依赖的唯一的特性是POSIX定义的特性。

还要注意Stefan的答案如何使用|| exit 0 在Bash命令结束时|| exit 0 ,以确保总体命令始终报告退出代码0 ,以确保npm不会中止处理。

尝试

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