Запустить процесс openoffice с python для использования с pyuno с использованием подпроцесса

Я использую эту команду для запуска openoffice:

soffice --accept="socket,host=localhost,port=8100;urp;StarOffice.Service" --headless --nofirststartwizard

Следующая команда гарантирует, что openoffice принимает соединения через порт 8100:

netstat -nap | grep office

выход:

tcp        0      0 127.0.0.1:8100          0.0.0.0:* LISTEN     2467/soffice.bin 

Скрипт Python для запуска процесса openoffice:

command = [
    'soffice',
    '--accept=socket,host=localhost,port=8100;urp;StarOffice.Service',
    '--headless',
    '--nofirststartwizard'
]
subprocess.Popen(command, shell=True)

По какой-то причине команда netstat ничего не выдает, когда я пытаюсь запустить openoffice с этим скриптом python. процесс есть, но он не принимает соединения. Что я делаю неправильно?

3 ответа

Решение

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

В Unix с shell=True оболочкой по умолчанию является /bin/sh. Если args является строкой, строка определяет команду для выполнения через оболочку.

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

Здесь вы должны просто удалить shell=True передать аргументы soffice вместо передачи аргументов в оболочку:

subprocess.Popen(command)

Использовать shell=Trueвам нужно собрать все аргументы в одну команду (аргументы, конечно, должны быть экранированы):

subprocess.Popen(command.join(' '), shell=True)

Я столкнулся с почти идентичной проблемой, и это сводило меня с ума, пока я не понял это. К счастью, исправить это просто.

Есть два способа исправить звонок Popen в оригинальном вопросе:

  1. либо вывезти , shell=True
  2. или добавить цитаты ко второму элементу в command как это:

    '--accept="socket,host=localhost,port=8100;urp;StarOffice.Service"'

Проблема в том, что оболочка неправильно разбирает аргументы без этих кавычек, поэтому либо не используйте оболочку (лучший способ), либо указывайте один аргумент, как указано выше. Я говорю, что лучше не использовать оболочку, потому что тогда просто отключить soffice, используя .terminate() метод объекта, возвращаемого Popen, В противном случае вам нужно использовать библиотеку, такую ​​как psutil, чтобы найти все ваши дочерние процессы и уничтожить их самостоятельно, потому что, как указал Скотт П., завершение оболочки не остановит soffice.

Скотт П: причина вашего первого звонка Popen не работает, потому что у вас есть кавычки во втором элементе, но вы не используете оболочку. Оболочка удаляет кавычки, когда анализирует командную строку, но, поскольку вы ее не используете, они остаются, и тогда soffice не интерпретирует аргумент так, как вы ожидаете. И именно поэтому ваш второй звонок Popen работает

Другая иллюстрация этой проблемы здесь: Ошибка вызова LibreOffice из Python

Выполняется следующее, но UNO-соединения с каналом не работают:

soffice = subprocess.Popen([ '/usr/bin/soffice', '--accept="pipe,name=hello;urp;"', '--norestore', '--nologo', '--nodefault', '--headless', ])

Если я выполняю это из терминала, соединения труб работают нормально:

/usr/bin/soffice --accept="pipe,name=hello;urp;" --norestore --nologo --nodefault --headless

Я могу видеть из моего отладчика, что subprocess.Popen успешно создан и что аргументы выглядят правильно и что у него есть pid. Я не уверен, почему это происходит. Кто-нибудь может объяснить это?

В конце концов я получил это работать следующим образом:

soffice = subprocess.Popen(' '.join([ '/usr/bin/soffice', '--accept="pipe,name=hello;urp;"', '--norestore', '--nologo', '--nodefault', '--headless', ]), shell=True)

Обратите внимание, однако, что закрытие пид с soffice.kill() оставляет позади некоторые процессы.

Смотрите вопрос здесь относительно этой проблемы: OpenOffice Forum Question 29873

Другие вопросы по тегам