Проблема с использованием подпроцесса для запуска команды 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))
Другие вопросы по тегам