特定のファイルを見つけて、各ファイルに対してPythonスクリプトを実行するMakefileを作成したいと思います。 Pythonスクリプトはsys.stdin
入力を受け入れます。
find $(W)/$(OVE) -name "*.xml" -print | \
while read x ; do \
cat $x | /opt/exp/bin/python2.7 process_results.py > $(W)/$(OVE)/$(dirname $x)_$(basename $x).xml \
done
出力は$(dirname $x)_$(basename $x).xml
空の_.xmlファイルです。
コマンドラインからこのコマンドを実行すると正常に動作しますが、Makefileでは機能しません。
このコマンドにどのような問題があるのか教えてください。
答え1
まず、シェルが解釈したようにドル記号を引用する必要があります。実際にはと$x
make によって解析され$(dirname $x)
ます$(basename $x)
。 whileループ本体の末尾にはセミコロンもありません。 make 実行結果を確認すると、シェルがこれについて文句を言うことがわかります。
find $(W)/$(OVE) -name "*.xml" -print | \
while read x ; do \
cat $$x | /opt/exp/bin/python2.7 process_results.py > $(W)/$(OVE)/$$(dirname $$x)_$$(basename $$x).xml; \
done
別の考えられる問題は、$(dirname $x)
部品がすでに含まれていることです$(W)/$(OVE)
。たとえば、$(W)
is foo
and $(OVE)
is bar
and $x
isの場合、おそらく作成したいsubdir/subsubdir/wibble.xml
同様のファイルを作成しようとします。ファイルをファイルに変換するのも奇妙です。元の拡張子を削除する予定の場合は、自分で作成する必要がありますが、再度追加するために拡張子を削除する必要はありません。そのため、次のように書きたい場合があります。foo/bar/foo/bar/subdir/subsubdir_wibble.xml.xml
foo/bar/foo/bar/subdir/subsubdir_wibble.xml.xml
.xml
.xml.xml
.xml
basename $$x .xml
find $(W)/$(OVE) -name "*.xml" -print | \
while read x ; do \
/opt/exp/bin/python2.7 process_results.py <$$x >$$(dirname $$x)_$$(basename $$x); \
done
もう1つの問題は、実行がprocess_results.py
失敗すると、makeが実行され続け、ビルドが成功したと報告されることです。エラーが発生した場合は、シェルに停止するように指示します。
set -e; \
find $(W)/$(OVE) -name "*.xml" -print | \
while read x ; do \
/opt/exp/bin/python2.7 process_results.py <$$x >$$(dirname $$x)_$$(basename $$x); \
done
答え2
$x
etc $(dirname $x)
... makeはそれらを独自の変数として解釈するので、makeによってすべて壊れます。 1行のシェルスクリプトで包み、Makefileから呼び出す方が良いでしょう。
答え3
シェルに渡すドル記号を引用する必要があります。それ以外の場合、make
シェルはそれを解釈しようとします。
-find $(W)/$(OVE) -name -print | \
while read x ; do \
cat $$x | /opt/exp/bin/python2.7 process_results.py \
> $(W)/$(OVE)/$$(dirname $$x)_$$(basename $$x).xml; \
done
単一ドル記号は変数拡張を実行します。ダブルドル記号は単一のドル記号としてコマンドラインに渡されます。