Search code examples
pythonjarenter

Python - Run .jar file with later input / "Enter"-Simulation


I'm writing a python script where at one point I need to run a .jar file.

If I run the .jar file without python from the normal CMD I start it by:

java -jar path\to\myFile.jar <some not important params>

The .jar is doing some stuff and prints also what it is doing right now.

After a time it reaches a point where it says something like:

Press Enter to repeat the same operation or enter (quit) or (q) to abort the operation

By pressing Enter the operation will process faster because it doesn't to completely new reinitialize.

What I tried is:

my_subprocess = subprocess.Popen("java -jar path\to\myFile.jar <some not important params>", shell=True, stdout=subprocess.PIPE,
                                 stdin=subprocess.PIPE)
keep_listening = True
while keep_listening:
    output_str = my_subprocess.stdout.readline().decode("utf-8").lower()
    print(output_str)
    keep_listening = "press enter to repeat" not in output_str

print("Try to 'enter'")
my_subprocess.stdin.write(b'\r\n')

keep_listening = True
while keep_listening:
    output_str = my_subprocess.stdout.readline().decode("utf-8").lower()
    print(output_str)
    keep_listening = "press enter to repeat" not in output_str

(This is just a simple and quick test setup and not the final code.)
It works fine till after the stdin. After that, nothing is happening anymore. So it seems like the .jar is not getting my 'Enter'.
It seems like the stdin is not pipeing my values. I also tried b'\n\r', b'\n', b'\r' as an "Enter".

What is wrong with my stdin? Or how can I do the whole thing better?


Solution

  • I got it to work by help of the comment of @Maged Saeed in this Post: https://stackoverflow.com/questions/28616018/multiple-inputs-and-outputs-in-python-subprocess-communicate#:~:text=This%20should%20be%20used%20with%20caution%20with%20line%20splitters%20and%20flushing%20the%20PIPE%20as%20it%20may%20create%20deadlocks.%20More%20could%20be%20reached%20in%20this%20great%20blog%20post%3A
    It says that I have to flush to avoid a deadlock and it works now.

    My code looks like this now:

    my_subprocess = subprocess.Popen("java -jar path\to\myFile.jar <some not important params>",
                                     shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE,
                                     text=True)
    keep_listening = True
    while keep_listening:
        output_str = my_subprocess.stdout.readline().lower()
        print(output_str)
        keep_listening = "press enter to repeat" not in output_str
    my_subprocess.stdout.flush()
    
    print("Try to 'enter'")
    my_subprocess.stdin.write('\n')
    my_subprocess.stdin.flush()
    
    keep_listening = True
    while keep_listening:
        output_str = my_subprocess.stdout.readline().lower()
        print(output_str)
        keep_listening = "press enter to repeat" not in output_str
    my_subprocess.stdout.flush()