我在Windows上有一个名为cnki-downloader.exe
的命令行Golang可执行文件(这里是开源的:https://github.com/amyhaber/cnki-downloader)。我想在Python中运行这个可执行文件,并与它交互(获取其输出,然后输入内容,然后获取输出,等等)
这是一个命令行程序,所以我认为它与MSVC构建的普通Windows命令行程序相同。我的代码是这样的:
# coding=gbk
from subprocess import Popen, PIPE
p = Popen(["cnki-downloader.exe"], stdin=PIPE, stdout=PIPE)
#p = Popen(["WlanHelper.exe"], stdin=PIPE, stdout=PIPE )
p.stdin.write( 'XXXXXX\n' )
result1 = p.stdout.read() # <---- we never return here
print result1
p.stdin.write( '1\n' )
result2 = p.stdout.read()
print result2
我的Python代码在使用Popen
参数的cnki-downloader.exe
调用时停止。然后我尝试了一个由MSVC(名为WlanHelper.exe
)构建的C命令行程序,它运行良好。我的脚本可以从exe获得输出。
所以我怀疑Golang可执行文件的命令行机制与本机C / C ++程序不同,其他语言(如Python)很难调用它并与之交互。
所以我想知道如何在其他语言如Python上与Windows上的Golang可执行文件进行交互?。如果这是不可能的,我也可以考虑修改Golang程序的源代码(因为它是开源的)。但我希望我不会走那一步。谢谢!
注意:
如果可能的话,我想直接调用这个Golang可执行文件,而不是将其修改为库并让Python导入它。如果我必须将Golang修改为库,为什么不删除交互方式并将所有内容都变成命令行参数?没有必要打扰写Golang库。所以请让我们假设Golang程序是闭源的。我不认为Python没有办法调用命令行Golang程序。如果是这种情况,那么我认为Golang 真的需要在与其他语言的互操作性方面得到改进。
答案 0 :(得分:1)
查看您正在使用的子进程模块的documentation,它们似乎有使用stdout.read()
和朋友的死锁警告:
警告当使用stdout = PIPE和/或stderr = PIPE时,这将会死锁 并且子进程为管道生成足够的输出 块等待OS管道缓冲区接受更多数据。使用 communication()以避免这种情况。
那么,也许尝试使用communicate代替?