<p>试图通过这样的文件将信息从一个进程(或线程)流到另一个进程(或线程)是个坏主意。你必须让编写器确保在每一行之后刷新文件(而不是在中间行刷新文件),你必须同步,这样你只在有新数据要读取时才读取文件,而不是尽可能快地旋转,你必须弄清楚如何检测何时有新的数据要读取(这是特定于平台的),等等</p>
<p>这正是管道的用途。事实上,考虑到这条线:</p>
<pre><code>from subprocess import call, Popen, PIPE
</code></pre>
<p>…我怀疑您复制并粘贴了一些使用管道执行操作的代码,否则,您为什么要导入<code>PIPE</code>?在</p>
<p>还有,我不知道你为什么认为你需要两条线。如果必须将输入发送到shell脚本并读取输出,那么使用两个线程可能会更容易。但您所要做的就是启动子进程,并在它可用时读取它的输出。所以只需从主线程的管道中读取。在</p>
<p>文档中有一些例子说明了如何做你想要的。在</p>
^{pr2}$
<p>迭代一个管道将会阻塞,直到另一行可用,然后读取整行,只要没有一行的长度超过<code>select.PIPE_BUF</code>(保证至少是512)。在</p>
<hr/>
<p>如果出于其他原因(例如,当这个线程收集输出时,您需要在主线程中执行一些其他工作),那么您可以使用与Python中任何其他线程完全相同的方法:创建一个<code>threading.Thread</code>子类,或者传递一个<code>target</code>函数。例如:</p>
<pre><code>def nnsh():
from subprocess import call, Popen, PIPE
p = Popen(['/bin/sh', 'nn.sh', '172.20.125.44', '10'], stdout=PIPE)
for line in p.stdout:
print line
p.wait()
t = threading.Thread(target=nnsh)
t.start()
# do a bunch of other stuff
t.join()
</code></pre>
<p>(当然,您可以让它成为一个守护线程,或者想出一种方法来通知它,而不是用无限的超时来连接它等等;如果您知道自己想要什么但不知道如何去做,请阅读一个基本教程或<code>threading</code>模块文档,如果您在某个地方卡住了,请另外发布一个新问题。)</p>
<hr/>
<p>如果在某些*nix平台上,您可能需要处理长得离谱的行(尽管在最新版本的OS X、FreeBSD、Linux或Solaris上似乎没有必要),那么您可能需要手动循环:</p>
<pre><code>buf = ''
while True:
buf += p.stdout.read(select.PIPE_BUF)
lines = buf.split('\n')
for line in lines[:-1]:
print line
buf = lines[-1]
</code></pre>