1

Pythonparent.pyのサブプロセスから stdout を読み取ろうとするスクリプトがあります。sub.py

parent.py:

#!/usr/bin/python
import subprocess
p = subprocess.Popen("sub.py", stdout=subprocess.PIPE)
print p.stdout.read(1)

そして、サブプロセスsub.py:

#!/usr/bin/python
print raw_input( "hello world!" )

parent.py実行すると、「hello world!」から「h」が出力されると予想されます。実際、ハングします。のshe-bang行に追加-uすることによってのみ、期待される動作を得ることができます。sub.py

これは私を混乱させます。シェルから直接実行する場合、-uスイッチは違いがないからです。sub.pyとは異なり、シェルはフラッシュされていない出力ストリームに何らかの形で関与していますparent.py

私の目標は、サブプロセスとして C プログラムを実行することなので、stdout をフラッシュするかどうかを制御することはできません。から同じことを実行している Python よりも、シェルがプロセスの stdout にアクセスしやすいのはsubprocess.Popenなぜですか? バッファをフラッシュしない C プログラムからそのような stdout ストリームを読み取ることはできますか?

編集:

これは、korylprince のコメントに基づく更新された例です...

## capitalize.sh ##
#!/bin/sh

while [ 1 ]; do
    read s
    echo $s | tr '[:lower:]' '[:upper:]'
done

########################################

## parent.py ##
#!/usr/bin/python 
from subprocess import Popen, PIPE

# cmd = [ 'capitalize.sh' ] # This would work
cmd = [ 'script', '-q', '-f', '-c', 'capitalize.sh', '/dev/null']

p = Popen(cmd, stdin=PIPE)
p.stdin.write("some string\n")
p.wait()

を実行するscriptと、改行が安定して表示されます (これが Python のサブプロセスである場合は、EOFerror が発生します)。

4

2 に答える 2

1

代替案は

p = subprocess.Popen(["python", "-u", "sub.py"], stdout=subprocess.PIPE)

またはここでの提案。

私の経験では、そうです、ほとんどのCプログラムから余分な労力なしで読むことができます。

Pythonインタープリターは、出力をバッファリングするために追加の手順を実行します。そのため、-u出力バッファリングを無効にするスイッチが必要です。あなたの典型的なCプログラムはこれをしません。

私は、Pythonインタープリター以外のプログラム(Cまたはその他)に遭遇したことはありません。これは、動作することを期待していて、サブシェル内にありませんでした。

于 2012-09-28T02:33:43.160 に答える
0

「-u」に関係なく、シェルが出力をすぐに読み取れる理由は、シェルから起動しているプログラムの出力が TTY に接続されているためです。stdout が TTY に接続されている場合、バッファリングされません (バッファするのは TTY 次第であるため)。Python 内から python サブプロセスを起動すると、stdout がパイプに接続されます。つまり、必要に応じて出力をフラッシュするサブプロセスに翻弄されます。

サブプロセスとの複雑なやり取りを行う場合は、このチュートリアルを参照してください。

于 2012-10-01T15:33:18.897 に答える