2

在我的标准 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)。

编辑:顺便说一下,那些奇怪<()的符号是过程替换。刚刚了解了他们。

4

2 回答 2

6

尝试

"bash -c 'diff <(ls dir1) <(ls dir2) || exit 0'"
于 2016-11-24T15:53:01.580 回答
5

用背景信息补充Stefan Hegny 的有用答案:

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

脚本通过将该行作为脚本参数传递给sh.

如果脚本以 0 以外的代码退出,那么这将中止该过程。

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

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

这将以同样的方式失败,因为当 Bash 被调用时sh,按照设计它不识别进程替换( <(...)),因为它在POSIX 兼容模式下运行

进程替换不是POSIX 的一部分:它们是特定于 Bash 的扩展(在zsh和中也支持ksh)。

为了可移植性,您应该只在您的条目中使用POSIX 强制的 shell 功能"scripts"- 除非您直接或通过调用其 shebang 行指定要使用的 shell的脚本文件显式调用特定的 shell (如 Stefan 的回答中)。

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

请注意 Stefan 的答案如何|| exit 0在 Bash 命令末尾使用,以确保整个命令始终报告 exit code0,以确保npm不会中止处理。

于 2016-11-24T16:36:43.210 回答