【问题标题】:Using subprocess for compiling a c++ program from python script使用子进程从 python 脚本编译 c++ 程序
【发布时间】:2019-02-22 18:24:52
【问题描述】:

我知道有一些类似的问题,这里是Invoking C compiler using Python subprocess commandsubprocess, invoke C-program from within Python,但我相信我的问题在某种意义上是不同的。

我需要编译一个使用一些 ROOT 库的 c++ 程序,所以我需要添加一些标志并链接一些库以进行编译。因此,我在普通 shell 上的编译行是:

> $($ROOTSYS/bin/root-config --cxx) $($ROOTSYS/bin/root-config --cflags --glibs) Analysis.cxx -o analysis.exe

效果很好。我想从我的 python 脚本中进行编译。我已经阅读了subprocess 模块的文档,但是如果在 subprocess.Popen 的调用中不使用shell=True 就无法获得解决方案,而且我并没有真正理解其中的区别。如果我使用:

process = Popen(["$($ROOTSYS/bin/root-config --cxx) $($ROOTSYS/bin/root-config --cflags --glibs) Analysis.cxx -o analysis.exe"], shell=True)

完成这项工作。但是,这个:

process = Popen(["$($ROOTSYS/bin/root-config --cxx)", "$($ROOTSYS/bin/root-config --cflags --glibs)", "Analysis.cxx", "-o", "analysis.exe"])

我得到了以下信息:

    Traceback (most recent call last):
  File "make_posanalysis.py", line 45, in <module>
    "Analysis.cxx", "-o", "analysis.exe"])
  File "Python/2.7.15/x86_64-slc6-gcc62-opt/lib/python2.7/subprocess.py", line 394, in __init__
    errread, errwrite)
  File "Python/2.7.15/x86_64-slc6-gcc62-opt/lib/python2.7/subprocess.py", line 1047, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

我想了解使用/不使用shell=True 之间的区别,因为这似乎是使脚本工作与否的原因。或者,我还有什么遗漏的吗?

【问题讨论】:

    标签: python python-2.7 shell subprocess root-framework


    【解决方案1】:

    来自documentation

    如果 args 是一个序列,第一项指定命令字符串,任何附加项将被视为 shell 本身的附加参数。也就是说,Popen 相当于:

    Popen(['/bin/sh', '-c', args[0], args[1], ...])
    

    所以它正在执行相当于:

    /bin/sh -c '$($ROOTSYS/bin/root-config --cxx)' '$($ROOTSYS/bin/root-config --cflags --glibs)' "Analysis.cxx", "-o", "analysis.exe"
    

    这不是你想要的,因为它只在第一个参数中执行$(...) 扩展;如果第一个参数中的命令引用$1$2 等,则其他所有内容都按字面意思理解,并成为位置参数。

    如果你想让 shell 解析所有内容,只需给出一个字符串。

    【讨论】:

    • 所以如果我做对了,没有 shell=True 就没有办法做到这一点,因为我需要执行两个 $(...) 扩展?
    • 是的,没错。您可以自己执行这些命令,保存输出,然后从中构建命令。
    • 因此,如果我将命令作为列表传递,那么基本上唯一真正的 shell 交互(调用 shell 命令,不确定我是否可以称其为“交互”)发生在第一个参数上。非常感谢!
    • 如果将命令作为列表传递,则第一个元素被视为 shell 命令,其余为参数。如果你把它作为一个字符串传递,整个字符串就是一个shell命令。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-04
    • 1970-01-01
    • 2012-07-31
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多