GNU Makefileでのプロセス置換


11

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つの出力を比較する方法はありますか?

回答:


20

/bin/shbashシステム上にある可能性がありますが、として呼び出されるとshbashPOSIXモードで実行されます(POSIXLY_CORRECT定義されている場合、またはで開始された場合--posix)。

このモードでは、プロセス置換は存在しません。

ソリューション:

all:
    command1 >file1
    command2 >file2
    diff file1 file2
    rm -f file1 file2

代替:

all:
    bash -c "diff <(command1) <(command2)"

または、Makefile変数SHELL/bin/bash次のように定義します。

SHELL=/bin/bash

移植性が必要な場合は、最初のソリューションを使用してください。への依存に問題がない場合はbash、2番目を選択します。さらにmake、GNU以外の実装について気にする必要がない場合は、3番目の実装を使用します。


設定についてSHELL:POSIX標準では、Makefileの実行可能ファイルは、system()Cライブラリ関数を使用して呼び出す必要があると規定されていmakeます。この関数は、SHELL環境変数の使用が保証されていません(実際には、標準で使用することはお勧めしません)。標準では、Makefile変数の設定SHELL環境変数に 影響を与えてはならないということもありますSHELLmakeただし、私が知っているほとんどの実装では、Makefile変数SHELLを使用してコマンドを実行します。

ユーティリティの根拠でmakeの提案は使用することbash -cです:

履歴MAKESHELL機能、および他のmake実装によって提供される関連機能は省略されました。一部の実装では、makeコマンドの実行に使用されるシェルをユーザーがオーバーライドできるようにするために使用されます。これは混乱を招きました。ポータブルのmake場合、シェルはmakefileライターが選択する必要があります。さらに、Makefileライターは、代替シェルを使用するように要求することはできませんが、Makefileを移植可能と見なします。代替シェルを指定するためのメカニズムを標準化することは可能ですが、既存の実装はそのようなメカニズムに同意しておらず、メイクファイル作成者はターゲットのルールでシェル名を指定することですでに代替シェルを呼び出すことができます。例えば:

python -c "foo"


bash一時ファイルを使用せずに、Makefileまたはdiff問題の他のソリューションで呼び出す方法はありますか?
ヨハネス

2つの一時ファイルを使用するだけです。これは、プロセス置換メソッドが内部で行う処理とほぼ同じです。
クサラナンダ

3
また、設定することができますSHELL/bin/bashのMakefileに。
Stephen Kitt 2017

1
@Johannes Kusalanandaが回答に情報を追加しました。これは、いくつかのオプションとそれらが使用できる状況を示しているので素晴らしいです。私はあなたがこの答えを受け入れたいと思います...(しかし、私は感情に感謝します!)
スティーブンキット

2
SHELL変数の使用がPOSIXに準拠していないという情報は非常に役に立ちました。多分それを使用する方が良いbash -cです。
ヨハネス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.