在我的标准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。刚刚了解了它们。
答案 0 :(得分:4)
使用背景信息补充Stefan Hegny's helpful answer:
来自https://docs.npmjs.com/misc/scripts:
通过将该行作为脚本参数传递给
sh
来运行脚本。如果脚本以0以外的代码退出,则会中止该过程。
具体来说,"scripts"
文件中目标package.json
条目的内容作为参数传递给sh -c
,因此命令行等效于命令:
sh -c 'diff <(ls dir1) <(ls dir2)'
会以同样的方式失败,因为 当Bash被调用为sh
时,设计它无法识别process substitutions({{1} }),因为它以 POSIX兼容模式运行。
流程替换不是 POSIX 的一部分:它们是 Bash特定的扩展名(在<(...)
和{{}}中也受支持{1}})。
为了便于移植,您应该只在zsh
条目中使用POSIX-mandated shell features - 除非您明确调用特定的shell (如在Stefan的回答中),或者直接使用,或者通过调用脚本文件,其shebang行指定要使用的shell。
不同的shell在不同的平台上充当ksh
,您可以依赖的唯一功能是POSIX定义的那些。
另外请注意Stefan的答案如何在Bash命令结束时使用"scripts"
,以确保整个命令始终报告退出代码sh
,以确保|| exit 0
不会中止处理。
答案 1 :(得分:3)
尝试
"bash -c 'diff <(ls dir1) <(ls dir2) || exit 0'"