Использование подпроцесса python для вызова команды python с разделенным пробелами списком - PullRequest
0 голосов
/ 28 февраля 2020

Я хотел бы вызвать подпроцесс python, который должен выполнить что-то в структуре

script.py -m opt -o oFile -i file1 file2 file3 ... 

Я пытаюсь построить команду с кодом, подобным:

inputfileList = "file1,file2,file3"
cmd = ['script.py', '-m opt', '-o oFile', '-i']
for file in inputfileList.split(','):
   cmd.append(file)
subprocess.call(cmd)

Это, однако, не работает должным образом, так как интерпретирует его как -i 'file1 file2 file3' вместо -i file1 file2 file3. Как я могу получить ожидаемое поведение?

1 Ответ

1 голос
/ 28 февраля 2020

Разумная вещь, которую нужно сделать для отладки, - это заменить script.py чем-то, что однозначно печатает ваш список аргументов, так что вы можете настроить этот список, пока он точно не будет соответствовать тому, что вы хотите. Например, заменив его на printf '%s\n':

inputfileList = "file1,file2,file3"
cmd = ['printf', r'%s\n', 'script.py', '-m opt', '-o oFile', '-i']
for file in inputfileList.split(','):
   cmd.append(file)
subprocess.call(cmd)

... , мы получим :

script.py
-m opt
-o oFile
-i
file1
file2
file3

file1 / file2 / file3 перечислить часть этого вывода совершенно нормально. Что неправильно означает -m и -o, что вы можете увидеть, если сравнить с выводом вашей команды оболочки, измененной таким же образом:

printf '%s\n' script.py -m opt -o oFile -i file1 file2 file3

... который выводит:

script.py
-m
opt
-o
oFile
-i
file1
file2
file3

..., таким образом, показывая результат, который вам нужно сделать, чтобы ваш Python совпадал, чтобы он вел себя как заявленная строка оболочки.


Примечание: %s\n это не самая лучшая форматная строка *1030* для этого, это просто лучшая /usr/bin/printf гарантированно поддерживается. Если вы хотите отображать непечатаемые символы, я бы предложил вместо этого использовать %q, поскольку это ksh / bash эквивалент Python '%r. Требуется больше работы, чтобы использовать его из Python, хотя:

inputfileList = "file1,file2,file3"
cmd = ['bash', '-c', r'''printf '%q\n' "$@"''', 'script.py', '-m opt', '-o oFile', '-i']
for file in inputfileList.split(','):
   cmd.append(file)
subprocess.call(cmd)

... показывает аргументы, которые ваш код Python генерирует в том же формате, в котором вы должны их поместить в командной строке оболочки, чтобы иметь тот же эффект . Таким образом, в этом случае:

-m\ opt
-o\ oFile
-i
file1
file2
file3

... показывая, что вам нужно покинуть пробелы, чтобы ваша оболочка вела себя так же, как ваш текущий Python (или переместите аргумент значения в отдельные строки из самих аргументов, чтобы Python вел себя как ваша текущая оболочка).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...