Проблема с использованием подпроцесса для запуска команды bash из Python
Выпуск:
Я не могу запустить pdal
команда bash из Python с использованием subprocess
,
Вот код
основанный на командах Running Bash в Python:
import os, subprocess
input = '/path/to/file.ply'
output = '/path/to/statfile.json'
if not os.path.isfile(output):
open(output, 'a').close()
bashcmd = ("pdal info --boundary "
+input
+" > "
+output
)
print("Bash command is:\n{}\n".format(bashcmd))
process = subprocess.Popen(bashcommand.split(),
stdout=subprocess.PIPE,
shell=True)
output, error = process.communicate()
print("Output:\n{}\n".format(output))
print("Error:\n{}\n".format(error))
Что дает мне этот вывод в консоли Python:
Bash command is:
pdal info --boundary /path/to/file.ply > /path/to/statfile.json
Output:
Usage:
pdal <options>
pdal <command> <command options>
--command The PDAL command
--debug Sets the output level to 3 (option deprecated)
--verbose, -v Sets the output level (0-8)
--drivers List available drivers
--help, -h Display help text
--list-commands List available commands
--version Show program version
--options Show options for specified driver (or 'all')
--log Log filename (accepts stderr, stdout, stdlog, devnull as
special cases)
--logtiming Turn on timing for log messages
The following commands are available:
- delta
- diff
- fauxplugin
- ground
- hausdorff
- info
- merge
- pcl
- pipeline
- random
- smooth
- sort
- split
- tindex
- translate
See http://pdal.io/apps/ for more detail
Error:
None
Похоже, что он прекратил читать аргументы команды после вызова 'pdal
', который печатает это справочное сообщение.
Если я скопирую вывод первой печати и вставлю его в терминал bash, он будет работать правильно, предоставляя мне выходной файл с нужными метаданными. Но из Python выходной файл не создается.
Вопрос:
Интересно, почему (например, что-то не так с перенаправлением или с тем фактом, что само вычисление может обычно занимать ~20 секунд?), И как выполнить эту команду из Python?
1 ответ
Здесь есть несколько ошибок.
- Вы используете неопределенную переменную
bashCommand
вместо того, который вы определили вышеbashcmd
, - Вы смешиваете вывод в дескриптор файла Python с перенаправлением оболочки.
- Вы не захватываете
stderr
процесса. (Я смутно предположу, что вам не нужна стандартная ошибка в любом случае.) - Вы не должны
split()
команда, если вы запускаете ее сshell=True
,
В более широком смысле, вам следует избегать shell=True
и пусть Python позаботится о перенаправлении для вас, подключив вывод к открытому файлу; и в наше время вы действительно не должны использовать subprocess.Popen()
если вы можете использовать subprocess.run()
или же subprocess.check_call()
или друзья.
import subprocess
input = '/path/to/file.ply'
output = '/path/to/statfile.json'
with open(output, 'a') as handle:
bashcmd = ['pdal', 'info', '--boundary', input]
#print("Bash command is:\n{}\n".format(bashcmd))
result = subprocess.run(bashcmd, stdout=handle, stderr=subprocess.PIPE)
# No can do because output goes straight to the file now
##print("Output:\n{}\n".format(output))
#print("Error:\n{}\n".format(result.stdout))