I want to automate a specific task using python.
This task includes, among some other things, connecting with ssh to a remote server, and running a specific program (call it prog.out) that may or may not ask for user input.
After some research and after weighting my options, I decided to use Python's Paramiko (which may turned out to be wrong, considering the below...).
Let's start with the easy possibility of prog.out not asking any input, but rather just prints some info to console:
int main(int argc, char* argv[]) {
printf("Hey there, fella\n");
printf("How are you this morning?\n");
printf("See ya...\n");
return 0;
}
which compiles to: prog.out, and sits on server_name, waiting to be executed.
So in that case:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect("server_name")
sin, sout, serr = client.exec_command('./prog.out')
for line in sout.readlines():
print(line, end = '')
Will work perfectly fine, and will print out whatever prog.out produces.
But if instead prog.out is:
int main(int argc, char* argv[]) {
printf("Hey there, fella\n");
printf("How are you this morning?\n");
printf("please enter an integer...\n");
int a;
scanf("%d", &a);
printf("you entered %d\n", a);
printf("see ya...\n");
return 0;
}
then the above python code will block at sout.readlines() (waiting for eof?)...
The way to avoid blocking in sout.readlines() is to provide input to prog.out by writing to its stdin pipe:
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect("server_name")
sin, sout, serr = client.exec_command('./prog.out')
sin.write('55\n')
for line in sout.readlines():
print(line, end = '')
But I can't know in advance if prog.out will require user's input or not...
I am looking for a robust way to run prog.out and let the user interact with it for as long as necessary.
Is there some indication when prog.out expects input?
EDIT
OK, I did a little experimenting, and found out that any attempt to read() from the channel will block, as long as prog.out has not exited, but prog.out can't exit as long as it wasn't provided with input...
How come I can't read bytes that were already sent by prog.out even when it is not finished yet?
I'd really love to simulate to the user as if he or she interacts directly with prog.out...