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

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で義務付けられているシェル機能のみを使用する必要があります-"scripts"特定のシェルを(Stefanの回答のように)明示的に呼び出すか、使用するシェルを指定するシバン行を持つスクリプトファイルを呼び出すことによって。

さまざまなシェルshがさまざまなプラットフォームで動作し、信頼できる唯一の機能は POSIX で定義されたものです。

また、Bashコマンドの最後でStefanの回答がどのように使用|| exit 0されているかにも注意してください。これにより、コマンド全体が常に終了コードを報告し0npm処理が中止されないようになります。

于 2016-11-24T16:36:43.210 に答える