Подтвердить что ты не робот

Как написать в подпроцесс Python 'stdin?

Я пытаюсь написать Python script, который запускает подпроцесс и записывает в подпроцесс stdin. Я также хотел бы определить действие, которое нужно предпринять, если подпроцесс сработает.

Процесс, который я пытаюсь запустить, - это программа под названием nuke, у которой есть своя встроенная версия Python, которую я хотел бы отправлять командам, а затем сказать, что она прекратит работу после команд выполнить. До сих пор я решил, что если я запустил Python в командной строке, а затем запустил nuke в качестве подпроцесса, тогда я могу ввести команды в nuke, но я бы хотел, чтобы это все a script, чтобы мастер-программа Python могла запускать nuke, а затем записывать в свой стандартный ввод (и, следовательно, в свою встроенную версию Python) и расскажите, как это сделать, и я написал script, который запускает nuke следующим образом:

subprocess.call(["C:/Program Files/Nuke6.3v5/Nuke6.3", "-t", "E:/NukeTest/test.nk"])

Тогда ничего не происходит, потому что nuke ждет ввода пользователя. Как мне теперь написать стандартный ввод?

Я делаю это, потому что я запускаю плагин с nuke, который заставляет его периодически прерываться при рендеринге нескольких кадров. Поэтому я хотел бы, чтобы этот script мог запустить nuke, сказать ему что-то сделать, а затем, если он сработает, попробуйте еще раз. Поэтому, если есть способ поймать сбой и все равно быть в порядке, это было бы здорово.

4b9b3361

Ответ 1

Лучше использовать communicate:

from subprocess import Popen, PIPE, STDOUT
p = Popen(['myapp'], stdout=PIPE, stdin=PIPE, stderr=PIPE)
stdout_data = p.communicate(input='data_to_write')[0]

"Лучше" из-за этого предупреждения:

Используйте функцию связи(), а не .stdin.write,.stdout.read или .stderr.read, чтобы избежать взаимоблокировок из-за того, что любой из других буферов буферов ОС заполняет и блокирует дочерний процесс.

Ответ 2

Вы можете предоставить файл-подобный объект аргументу stdin subprocess.call().

Здесь документация для объекта Popen.

Чтобы захватить вывод, вместо этого вы должны использовать subprocess.check_output(), который принимает аналогичные аргументы. Из документации:

>>> subprocess.check_output(
...     "ls non_existent_file; exit 0",
...     stderr=subprocess.STDOUT,
...     shell=True)
'ls: non_existent_file: No such file or directory\n'

Ответ 3

Вот как это выглядит для коммерческой версии NUKE 11.3v4 на Windows 10:

import subprocess

# Run NUKE script in Terminal mode on Windows machine...
subprocess.Popen(['C:/Program Files/Nuke11.3v4/Nuke11.3.exe', '-t', 'E:/NukeTest/test.nk'], stdin=PIPE, stdout=PIPE)

Вот как это работает для некоммерческой версии NUKE 11.3v4 на macOS 10.14:

import subprocess
from subprocess import Popen, PIPE
import time

# Run NUKE script in Terminal mode on MacOS machine...
np = subprocess.Popen(['/Applications/Nuke11.3v4/NukeX11.3v4 Non-commercial.app/NukeX11.3v4 Non-commercial', '-t', '/Users/<username>/Desktop/test.nknc'], stdin=PIPE, stdout=PIPE)

# Choose a method to wait for the subprocess to finish...
np.wait() 
time.sleep(5)        

data = np.communicate(input='data')[0]

print(data)

Результат выглядит следующим образом:

'''
NukeX 11.3v4, 64 bit, built May  1 2019.
Copyright (c) 2019 The Foundry Visionmongers Ltd.  All Rights Reserved.
Non-commercial mode active.
Licence expires on: 2019/7/27
(11, 3, 4)
('darwin', 'posix')
/Applications/Nuke11.3v4/Nuke11.3v4.app/Contents/MacOS/../Frameworks/Python.framework/Versions/Current/
Disk cache /var/tmp/nuke-u501/ViewerCache/??: 424MB (5% of 10240MB) used in 81 files.

'''

Также вы можете запустить подпроцесс в графическом интерфейсе, используя флаг -v для изображений:

subprocess.Popen(['C:/Program Files/Nuke11.3v4/Nuke11.3.exe', '-v', 'E:/NukeTestImages/image.exr'], stdin=PIPE, stdout=PIPE)

Надеюсь это поможет.

Ответ 4

from subprocess import Popen, PIPE, STDOUT
p = Popen(['myapp'], stdout=PIPE, stdin=PIPE, stderr=PIPE)
stdout_data = p.communicate(input='data_to_write')[0]

работает только в том случае, если "myapp" не принимает аргументов.