0

I have the program that takes about 4-5 seconds to launch each time I open it with Python's subprocess:

command = ['./command', arg1] # my command to launch the program
p = subprocess.Popen(command, stdout=subprocess.PIPE, bufsize=-1) # launch the program (takes about 4 seconds) 
print(p.stdout.read()) # display output

I would like to avoid waiting for the program to launch each time and keep it running instead and pass the new args. Is there a way to keep the command running and passing in new arguments to output?

I was hoping something like this:

  p = launch_the_program()
  p.run(arg1)
  p.run(arg2)
  p.run(arg3)
  p.close()

I understand that this question is similar to mine, but the answer from there I think is outdated since it didn't work for me.

EDIT: the linked answer is about passing input to the program instead of arguments (which is what I'm trying to achieve). Is there a workaround that can keep program running and accepting new arguments without restarting?

Medita Inc.
  • 49
  • 1
  • 10
  • What was the problem when you tried to apply what is written in the accepted answer to the question you have linked? – mkrieger1 Nov 08 '20 at 12:35
  • 1
    Do you want to pass new *arguments* (like ``arg1``) or new *input* (as in the linked question)? By their nature, arguments can only be passed when starting a program. – MisterMiyagi Nov 08 '20 at 12:45
  • @MisterMiyagi I would like to pass arguments. Isn’t there any workaround? – Medita Inc. Nov 08 '20 at 13:53
  • @mkrieger1 I have receiverd PIPE broken error – Medita Inc. Nov 08 '20 at 13:56
  • @AskoldIlvento Could you elaborate / provide an example? – Medita Inc. Nov 08 '20 at 13:57
  • @MisterMiyagi I'm trying to find a way to feed the new arguments without restarting the program. – Medita Inc. Nov 08 '20 at 13:58
  • @AskoldIlvento Ideally I would like to keep the process open and wait for the user to provide an input, so that the program then would immedialty start processing the input and display output – Medita Inc. Nov 08 '20 at 14:05
  • @mkrieger1 Also, as MisterMiyagi pointed out, in the linked question new input was being provided instead of new arguments. I would like to find a way to feed the program new arguments without it restarting – Medita Inc. Nov 08 '20 at 14:07
  • 1
    "I would like to pass arguments. Isn’t there any workaround?" No, because that does not make sense. Arguments are by definition the stuff passed in at startup. You cannot pass in arguments to a running program, just as the running program cannot receive arguments. Please reconsider your requirements, and/or clarify how "``./command``" expects input and responds to it. – MisterMiyagi Nov 08 '20 at 14:20
  • @MisterMiyagi The program that I'm using is this: https://bellard.org/nncp/gpt2tc.html. It doesn't have REPL feature, which would allow new input without restarting and I was hoping to find a workaround for that – Medita Inc. Nov 08 '20 at 14:23
  • **Arguments** are set on startup. Inherently, by nature, you cannot change them without restarting. – Charles Duffy Nov 08 '20 at 14:27
  • ...so, given what you're trying to accomplish, I would suggest contacting Fabrice Bellard with a feature request to be able to control the program at hand via stdin rather than command line arguments. – Charles Duffy Nov 08 '20 at 14:30
  • It's either that, or try linking in the executable he provides `dlopen`-style and directly calling its `main` more than once; but for a program not designed to be called that way, it's liable to fail, leak memory, redo the initialization steps you're trying to skip, or do some combination of the above. I don't recommend the approach for someone who doesn't already have the level of reverse engineering background and experience to have thought of it themselves. – Charles Duffy Nov 08 '20 at 14:32
  • 1
    Also, 4-5 seconds is long enough that you're almost certainly waiting for initialization that happens _after_ `main()` is called, rather than just for regular linking and loading; so while it is possible to prelink and preload and fork off instances that are ready to call `main()`, that technique is unlikely to help you here. – Charles Duffy Nov 08 '20 at 14:52

1 Answers1

1

When run returns, the program you ran has exited and is no longer in memory. There's no pre-initialized copy still in RAM to reuse (by re-invoking its main with different arguments).

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441