如何在 Makefile 中运行 Python 脚本

如何在 Makefile 中运行 Python 脚本

我想编写一个 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以及$xis 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

单个美元符号进行变量扩展。双美元符号作为单个美元符号传递到命令行。

相关内容