Почему stdout ведет себя по-разному для подпроцесса. Open вызывается с shell = True против False? - PullRequest
2 голосов
/ 01 декабря 2011

В качестве минимального примера я хочу запустить «ping website.com» как на удаленном, так и на локальном компьютере и распечатать вывод с обоих параллельно на локальный стандартный вывод.

Я использую многопроцессорность для вызова обеих функцийработать параллельно.Каждая функция использует subprocess.Popen («ping ...»).Если Popen вызывается с shell = True, печатается только вывод с одного аппарата, и, наконец, позже выводится вывод с другого аппарата.Если Popen вызывается с shell = False, выходные данные печатаются параллельно.Почему?

Минимальный пример (shell = True в первой функции):

#!/usr/bin/env python

import multiprocessing
import subprocess
import sys
import rpyc

def run_remote(ip, command, arg):
    '''Connect to a pc using rpyc package, print remote stdout to local stdout.'''
    remote_pc = rpyc.classic.connect(ip) # Connect
    remote_pc.modules.sys.stdout = sys.stdout   # Redirect remote stdout to local stdout
    child = remote_pc.modules.subprocess.Popen([command, arg], shell=True, stdout=remote_pc.modules.subprocess.PIPE)
    while True:
        out = child.stdout.readline()
        if out == '' and child.poll() != None:
            break
        if out != '':
            print "%s" % out
            remote_pc.modules.sys.stdout.flush()

def run_local(command, arg):
    child = subprocess.Popen([command, arg], stdout=subprocess.PIPE)
    while True:
        out = child.stdout.readline()
        if out == '' and child.poll() != None:
            break
        if out != '':
            print "%s" % out
            sys.stdout.flush()

if __name__ == '__main__':
    print "Started."
    remote_ip = "192.168.1.135" # must be running rpyc_classic.py
    # CREATE PROCESSES
    pc1 = multiprocessing.Process(target=run_remote, name="pc1", args=(remote_ip,"ping","yahoo.com"))
    pc3 = multiprocessing.Process(target=run_local, name="pc3", args=("ping","google.com"))
    # START PROCESSES
    pc1.start()
    pc3.start()
    # WAIT FOR PROCESSES
    pc1.join()
    pc3.join()
    print "Done."
...