外部システム コマンドでユーザー入力が必要になる場合があるスクリプトを作成しています。私はそれを適切に処理することができません。os.popen4 と subprocess モジュールを使用してみましたが、目的の動作を実現できませんでした。
以下の例は、「cp」コマンドを使用してこの問題を示しています。(「cp」コマンドは、この問題を示すために使用されます。シナリオによっては、同様にユーザーの応答を求める可能性のある別の exe を呼び出しています)。この例では、ディスク上に 2 つのファイルが存在し、ユーザーが file1 を file2 にコピーしようとすると、conformer メッセージが表示されます。
proc = subprocess.Popen("cp -i a.txt b.txt", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,)
stdout_val, stderr_val = proc.communicate()
print stdout_val
b.txt?
proc.communicate("y")
この例では、stdout/stderr のみを読み取って出力すると、後でユーザーの入力に基づいて「y」または「n」を書き込もうとすると、チャネルが閉じているというエラーが発生します。
最初にstdoutを出力してから、ユーザー入力を取り、後でstdinを書き込む必要があるように、Pythonでこの動作を達成するのを手伝ってくれる人がいますか?
python の subprocess.PIPE での非ブロッキング読み取りから別の解決策 (スレッド化) を見つけましたが、それが役立つかどうかはわかりません。しかし、それはcpコマンドからの質問を印刷しているようです.コードを変更しましたが、スレッドコードに書き込む方法がわかりません.
import sys
from subprocess import PIPE, Popen
from threading import Thread
try:
from Queue import Queue, Empty
except ImportError:
from queue import Queue, Empty
ON_POSIX = 'posix' in sys.builtin_module_names
def enqueue_output(out, queue):
for line in iter(out.readline, b''):
queue.put(line)
out.close()
p = Popen(['cp', '-i', 'a.txt', 'b.txt'],stdin=PIPE, stdout=PIPE, bufsize=1, close_fds=ON_POSIX)
q = Queue()
t = Thread(target=enqueue_output, args=(p.stdout, q))
t.start()
try:
line = q.get_nowait()
except Empty:
print('no output yet')
else:
pass