我想编写一个 Makefile 来查找特定文件并在每个文件上运行一个 Python 脚本。 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
首先,您需要引用 shell 解释的美元符号。事实上,$x
和$(dirname $x)
是$(basename $x)
由 make 解析的。您还缺少 while 循环体末尾的分号。检查运行 make 的输出,您应该看到 shell 对此进行抱怨。
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)
isfoo
和$(OVE)
isbar
以及$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
另一个问题是,如果任何一次运行process_results.py
失败,make 将继续运行并仍然报告构建成功。如果发生错误,则告诉 shell 停止:
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
等等$(dirname $x)
...都会被 make 破坏,因为它会将它们解释为自己的变量。最好将其包装在一行 shell 脚本中并从 Makefile 中调用它。
答案3
您需要引用要传递给 shell 的美元符号,否则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
单个美元符号进行变量扩展。双美元符号作为单个美元符号传递到命令行。