-2

I have a command-line Golang executable on Windows named cnki-downloader.exe (open-sourced here: https://github.com/amyhaber/cnki-downloader). I want to run this executable in Python, and interact with it (get its output, then input something, then get output, and so on)

It's a command-line program, so I thought it's the same as a normal Windows command-line program built by MSVC. My code is like this:

# 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

My Python code halts at the Popen call with cnki-downloader.exe parameter. Then I tried a C command-line program built by MSVC (named WlanHelper.exe), it runs well. My script can get the output from the exe.

So I suspect that the command-line mechanism of the Golang executable is different from a native C/C++ program, and it's difficult for other languages (like Python) to call and interact with it.

So I want to know how to interact with a Golang executable on Windows in other languages like Python?. If this is impossible, I can also consider modifying the Golang program's source code (because it's open source). But I hope I won't go that step. Thanks!


NOTE:

If possible, I want to call this Golang executable directly, instead of modifying it into a library and let Python import it. If I have to modify the Golang into a library, why not just remove the interactive manner and make everything into command-line parameters? There's no need to bother writing a Golang library. So please let's assume the Golang program is closed-sourced. I don't think there's no way for Python to call a command-line Golang program. If this is the case, then I think Golang REALLY needs to be improved in the interoperability with other languages.

hsluoyz
  • 2,739
  • 5
  • 35
  • 59
  • Possible duplicate of [Writing a Python extension in Go (Golang)](http://stackoverflow.com/questions/12443203/writing-a-python-extension-in-go-golang) – captncraig Oct 19 '16 at 05:01
  • @captncraig I think that solution requires to compile the Golang into a library instead of the current executable. Is there a way not to change the Golang executable's source code? – hsluoyz Oct 19 '16 at 05:14
  • Ah, perhaps the fact that your target app is in go is tangential to your problem. Seems there is some problem interacting with a child process from python. – captncraig Oct 19 '16 at 05:48

1 Answers1

1

Looking at the documentation for the subprocess module you are using, it seems they have a warning about deadlocks using stdout.read() and friends:

Warning This will deadlock when using stdout=PIPE and/or stderr=PIPE and the child process generates enough output to a pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use communicate() to avoid that.

So, maybe try using communicate instead?

captncraig
  • 22,118
  • 17
  • 108
  • 151