
bash プロンプトでは、疑似ファイルを使用して diff を実行できます。
diff <(echo test) <(echo test)
これをそのまま Makefile に追加すると失敗します。
all:
diff <(echo test) <(echo test)
エラー (ヒント: このシステムでは /bin/sh は /bin/bash を指します):
/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `diff <(echo test) <(echo test)'
これはどういう意味ですか? また、一時ファイルを使用せずに 2 つの出力を比較する方法はありますか?
答え1
/bin/sh
bash
はシステム上に存在している可能性がありますが、 として呼び出されるとsh
、bash
は POSIX モードで実行されます (POSIXLY_CORRECT
が定義されているか、 で起動された場合と同様--posix
)。
このモードでは、プロセスの置換は存在しません。
解決策:
明示的な一時ファイルを使用する:
all: command1 >tmpfile command2 | diff tmpfile - rm -f tmpfile
bash -c
インライン スクリプトを使用します。all: bash -c 'diff <(command1) <(command2)'
Makefile 変数を
SHELL
次のように定義します (またはシステム上の/bin/bash
パスを指定します)。bash
SHELL=/bin/bash
移植性が必要な場合は、最初のソリューションを選択してください。 への依存関係が問題ない場合はbash
、2 番目のソリューションを選択してください。さらに、GNU 以外の実装を気にする必要がない場合はmake
、3 番目のソリューションを使用してください。
設定についてSHELL
: POSIX 標準では、Makefile 内の実行ファイルは、system()
C ライブラリ関数を使用してで呼び出す必要があるとされていますmake
。この関数は、環境変数を使用することが保証されていませんSHELL
(実際、標準では使用が推奨されていません)。標準では、Makefile 変数の設定が、SHELL
環境変数 SHELL
ただし、私が知る限りのほとんどの実装では、コマンドを実行するためにmake
Makefile 変数が使用されます。SHELL
の提案make
ユーティリティの根拠使用するにはbash -c
:
歴史的な
MAKESHELL
機能、および他の実装によって提供される関連機能はmake
省略されました。一部の実装では、make
コマンドを実行するために使用するシェルをユーザーがオーバーライドできるようにするためにこの機能が使用されています。これは混乱を招きました。ポータブル の場合make
、シェルは makefile ライターによって選択される必要があります。さらに、makefile ライターは代替シェルの使用を要求しながら、makefile をポータブルと見なすことはできません。代替シェルを指定するためのメカニズムを標準化することは可能ですが、既存の実装ではそのようなメカニズムについて合意されておらず、makefile ライターはターゲットのルールでシェル名を指定して代替シェルを呼び出すことができます。たとえば、次のようになります。
python -c "foo"