web-dev-qa-db-ja.com

Pythonサブプロセス 'stdinに書き込むにはどうすればよいですか?

サブプロセスを開始し、サブプロセスstdinに書き込むPythonスクリプトを記述しようとしています。サブプロセスがクラッシュした場合に実行するアクションを決定できるようにしたいと思います。

私が開始しようとしているプロセスは、nukeと呼ばれるプログラムです。これには、Pythonのコマンドを送信できるようにしたい独自の組み込みバージョンがあります。コマンドの実行後に終了するように指示しますこれまでのところ、コマンドプロンプトでPythonを起動し、サブプロセスとしてnukeを開始すると、コマンドをnukeに入力しますが、マスターPythonプログラムがnukeを開始してから書き込むことができるように、これをすべてスクリプトに入れたいです。 標準入力 に(したがって、Pythonの組み込みバージョンに)そして、おしゃれなことをするように指示するため、次のようにnukeで始まるスクリプトを作成しました。

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

nukeはユーザー入力を待機しているため、何も起こりません。標準入力に書き込むにはどうすればよいですか?

これは、複数のフレームをレンダリングするときに断続的にクラッシュするnukeを使用してプラグインを実行しているためです。したがって、このスクリプトでnukeを起動し、何かをするように指示して、クラッシュした場合はもう一度やり直してください。したがって、クラッシュをキャッチし、それでも大丈夫な方法があれば、それは素晴らしいことです。

52
jonathan topf

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ではなく、communicate()を使用して、他のOSパイプバッファーがいっぱいになり、子プロセスをブロックすることによるデッドロックを回避します。

72
jro

subprocess.call()stdin引数にファイルのようなオブジェクトを提供できます。

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'
0
user626998

Windows 10のNUKE 11.3v4の商用バージョンでは、これは のように見えます

import subprocess

# Run NUKE's 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)

macOS 10.14上のNUKE 11.3v4の非商用バージョンでの動作は次のとおりです。

import subprocess
from subprocess import Popen, PIPE
import time

# Run NUKE's 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フラグを使用して、GUIでサブプロセスを実行できます。

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

お役に立てれば。

0
ARGeo