0

次のルールを持つMakefleがあります

bash -c "find . |grep -E '\.c$|\.h$|\.cpp$|\.hpp$|Makefile' | xargs cat | wc -l"

make が引用された bash スクリプトを実行し、プロジェクトの行数を返すことを期待しています。

ターミナルでコマンドを直接実行すると機能しますが、makefile では機能しません。スクリプトから削除する$と、機能します...しかし、期待どおりではありません(*.{c,cpp,h,hpp,Makefile}.

bash -cスクリプトが正しく実行されないのはなぜですか?

4

2 に答える 2

1

次のようにルールを記述すると、必要な結果が得られるはずです。

target:
    @echo $(shell find . | grep -E '\.c$$|\.h$$|\.cpp$$|\.hpp$$|Makefile' | xargs cat | wc -l)
于 2012-08-02T21:22:04.970 に答える
0

Makefile では、$ は $(HEADERS) などの make 変数に使用されます。ここで、HEADERS は以前に = を使用して定義されていました。

インライン bash で $ を使用するには、それらを二重にしてエスケープする必要があります。$$VAR はシェル変数を参照し、.c$$ などは、使用している正規表現の $ をエスケープする必要があります。

以下は、達成しようとしているものの $ をエスケープするのに十分なはずです

bash -c "find . |grep -E '\.c$$|\.h$$|\.cpp$$|\.hpp$$|Makefile' | xargs cat | wc -l"

さらに、次の宣言を追加すると、デフォルトの /bin/sh ではなく、Makefile で bash をグローバルに使用できます。

SHELL = /bin/bash

上記により、bash -c と引用符を必要とせずに find コマンドを使用できるはずです。SHELL が上記のように定義されている場合、次のように動作するはずです。

find . |grep -E '\.c$$|\.h$$|\.cpp$$|\.hpp$$|Makefile' | xargs cat | wc -l

また、この目的で SubShell が使用されることもよくあります。これらは () で作成されます。これにより、内部シェルによって定義されたすべての変数が、そのシェルとそのコマンド グループに対してローカルになります。

于 2014-08-31T15:11:40.443 に答える