Использование подпроцесса для компиляции программы на С ++ из скрипта Python - PullRequest
0 голосов
/ 22 февраля 2019

Я знаю, что есть некоторые подобные вопросы, здесь Вызов компилятора C с использованием подпроцесса Python и подпроцесс, вызов C-программы из Python , но я считаю, что мой вопрос в некотором смыслеразные.

Мне нужно скомпилировать программу на c ++, которая использует некоторые библиотеки ROOT , поэтому мне нужно добавить некоторые флаги и связать некоторые библиотеки для компиляции.Поэтому моя строка компиляции на обычной оболочке:

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

, которая работает хорошо.Я хочу сделать эту компиляцию из моего скрипта Python.Я прочитал документацию для модуля подпроцесса , но я не смог найти решение без использования 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, так как это, кажется, причиназаставить скрипт работать или нет.Или что-то еще мне не хватает?

1 Ответ

0 голосов
/ 22 февраля 2019

Из документации :

Если args является последовательностью, первый элемент задает командную строку, а любые дополнительные элементы будут рассматриваться как дополнительные аргументы для самой оболочки,То есть 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 и т. д.

Если вы хотите, чтобы все, анализируемое оболочкой, анализировалось, просто дайте одну строку.

...