sous-processus popen.communiquer() vs stdin.write() et la sortie standard stdout.lire()

J'ai remarqué deux comportements différents avec deux approches qui devraient avoir le même résultat.

Le but d'exécuter un programme externe à l'aide de sous-processus module, envoyer des données et de lire les résultats.

Le programme externe est PLINK, la plate-forme est WindowsXP, une version de Python 3.3.

L'idée principale-

execution=["C:\\Pr..\\...\\plink.exe", "-l", username, "-pw", "***", IP]
a=subprocess.Popen(execution, bufsize=0, stdout=PIPE, stdin=PIPE, stderr=STDOUT, shell=False)
con=a.stdout.readline()
if (con.decode("utf-8").count("FATAL ERROR: Network error: Connection timed out")==0):
   a.stdin.write(b"con rout 1\n")
   print(a.stdout.readline().decode("utf-8"))
   a.stdin.write(b"infodf\n")
   print(a.stdout.readline().decode("utf-8"))
else:
   print("ERROR")
a.kill()

So far So good.

Maintenant, je veux être capable de faire une boucle (après chaque écriture dans le sous processus de la stdin), qui attend jusqu'expressions du FOLKLORE de la sous-processus de la sortie standard (stdout), l'imprimer, puis un autre stdin commande, et ainsi de suite.

J'ai donc d'abord essayé ce que les discussions précédentes sur le même sujet rendement (en direct de la sortie du sous-processus de commande, lire les sous-processus stdout ligne par ligne, python, sous-processus: la lecture de la sortie de sous-processus) .

Et ça n'a pas fonctionné (il se bloque jamais) parce que le PLINK processus est encore en vie jusqu'à ce que je le tuer moi-même, donc il ne sert à rien d'attendre la sortie standard (stdout) de la sous-processus pour atteindre les expressions du FOLKLORE ou de faire une boucle tant que stdout est vrai, car il sera toujours vrai que j'ai de le tuer.

J'ai donc décidé de lire à partir de stdout deux fois à chaque fois que je suis en train d'écrire sur stdin (suffisant pour moi)-

execution=["C:\\Pr..\\...\\plink.exe", "-l", username, "-pw", "***", IP]
a=subprocess.Popen(execution, bufsize=0, stdout=PIPE, stdin=PIPE, stderr=STDOUT, shell=False)
con=a.stdout.readline()
if (con.decode("utf-8").count("FATAL ERROR: Network error: Connection timed out")==0):
   a.stdin.write(b"con rout 1\n")
   print(a.stdout.readline().decode("utf-8"))
   print(a.stdout.readline().decode("utf-8"))   //the extra line [1]
   a.stdin.write(b"infodf\n")
   print(a.stdout.readline().decode("utf-8"))
   print(a.stdout.readline().decode("utf-8"))   //the extra line [2]
else:
   print("ERROR")
a.kill()

Mais le premier extra readline() se bloque toujours, comme je le comprends, pour la même raison que j'ai mentionnés. Le premier extra readline() attend toujours pour la sortie, parce que la seule sortie était déjà lire dans le premier readline(), et parce que PLINK est vivant, la fonction juste de "s'asseoir" là et attend pour une nouvelle sortie ligne pour obtenir.

J'ai donc essayé ce code, en espérant la même accrocher parce que PLINK ne meurt jamais, jusqu'à ce que je le tuer,

execution=["C:\\Pr..\\...\\plink.exe", "-l", username, "-pw", "***", IP]
a=subprocess.Popen(execution, bufsize=0, stdout=PIPE, stdin=PIPE, stderr=STDOUT, shell=False)
con=a.stdout.readline()
if (con.decode("utf-8").count("FATAL ERROR: Network error: Connection timed out")==0):
   a.stdin.write(b"con rout 1\n")
   print(a.stdout.readline().decode("utf-8"))
   a.stdin.write(b"infodf\n")
   print(a.stdout.readline().decode("utf-8"))
   print(a.communicate()[0].decode("utf-8"))     //Popen.communicate() function
else:
   print("ERROR")
a.kill()

J'ai essayé parce que, selon la documentation de communicate(), la fonction d'attendre jusqu'à ce que le processus est terminé, et puis il a fini. Aussi, il lit à partir de la sortie standard jusqu'à EOF. (même que de l'écriture et de la lecture stdout et stdin)

Mais communicate() finitions et n'accroche pas, au contraire de la précédente bloc de code.

Ce qui me manque ici? pourquoi lors de l'utilisation de communicate() la PLINK se termine, mais lors de l'utilisation de readline() il ne fonctionne pas?

OriginalL'auteur user2162550 | 2014-01-15