Reputation: 1153
I have a console utility written in java which checks some remote data, outputs possible options to the user, and then waits for user input to choose one of the options. The utility uses command line arguments to determine which data to check and what to show to the user. I want to see output of running this utility multiple times with different arguments to find an optimal solution. If I do it manually my workflow looks something like this
./command arg1 arg2
*waits several seconds for the output
*analyses output
*if found the desired option chooses it by typing its value
*else presses ^C and carries on searching
./command args2 arg1
*...
./command arg1 arg3
*...
It is annoying to do manually, it is problematic to change source code of the utility, therefore I want to automate it using Python
I found there are several options to execute a shell command and capture its output, but I cannot find how to register callback for to capture the moment when shell command starts waiting for user input
He are my intentions in code
import itertools
some_args = ['ARG1', 'ARG2', 'ARG3']
def execute(comb):
# execute ./command comb[0] comb[1]
# is it possible to have something like this?
# register_on_input_waiting(do_something_with_output)
pass
def do_something_with_output(output):
# TODO: gather all the output, analyze it in code, and present best option to the user
pass
for comb in itertools.combinations(some_args, 2):
comb_rev = comb[::-1]
execute(comb)
execute(comb_rev)
Upvotes: 0
Views: 107
Reputation: 227
Actually I found a way, how to check, if a program waits for input. However, it is not plattform compactible and in my opinion this is more hacking, than engineering.
On a X86 64 Linux system I can run:
gdb <my_program>
(gdb) catch syscall read
(gdb) command 1
>if $rdi != 0
>continue
>end
>end
(gdb) run
Now gdb will interrupt the program everytime, it tries to read from stdin. I am pretty sure, that there are python interfaces to gdb.
Note, that is works on X86 64 Architecture and on Linux. Other operating systems may have different system calls and $rdi is architecture specific.
Upvotes: 1
Reputation: 227
If your program is interactive, the best way to automate it, is using pexpect
(pythons expect implementation).
You then start your process with:
p = pexpect.spawn("...")
If you know the questions, the program asks, you can filter for them:
pat = [ "Please enter (.+): ", ...]
ind = p.expect(pat)
if ind == 0:
print("User asked for " + p.match.group(1))
In general, it's not possible to find the moment, when the program expects input.
Upvotes: 0