Identifying that a command has finished (ShellStream)

Feb 16, 2015 at 4:59 PM
Suppose I'm using ShellStream in the following way:
shellStream.Write("./interactive_command.sh\n"); // Command, that will ask me to prompt something
shellStream.Write("my first string\n");  // My first response to the prompt
shellStream.Write("my second string\n"); // My second response to the prompt
How do I know that the command './interactive_command.sh' has finished working and I can dispose ShellStream?
By the way, the command './interactive_command.sh' awaits the response silently, that is without any asking strings.
Feb 21, 2015 at 12:15 AM
Did you open an ssh connection to the remote machine, get a "shell" and then execute "./interactive_command.sh" within that shell?
If that's the case, then there's really no way for the "connection" itself to know if a command has finished because it's executing in the context of the shell.

This guy had a similar problem and appended ; echo "MAGICSTRING" to every command and then searched for "MAGICSTRING"
http://blog.james-carr.org/2006/07/11/ssh-over-java/

You might try using SSHCommand passing in all three lines as one command...
Feb 21, 2015 at 3:20 PM
We have solved our local problem (as far as I understand, it is not a general solution) by adding into source code overloaded version of RunCommand(, Action<> InteractiveResponse). We have found that, when an interactive program asks for input (even if the prompt is empty) SshCommand's method Channel_DataReceived() gets fired. When this happens, we immediately ::SendData(...). These data are then pushed by sshd into remote program's stdin. It seems that these follow up messages do not violate any RFC.
Feb 23, 2015 at 4:22 PM
I didn't realize you were simply attempting to respond to the prompts. I thought you were trying to figure out when the whole program had finished executing.

The Channel_DataReceived() bit is good to know.

FWIW, some other ideas to consider in future cases:

I expect that because how the typical read command is done that the code could send data down the pipe whenever and it would simply buffer on stdin until the process in question looked for it (reading it in and processing the input one line at a time regardless of how many lines were "prequeued").

For example, if the code executed shellStream.Write("interactive_command.sh\nmy first string\nmysecond string\n") as one command, I'd expect it to work.
Or something like: echo "my first line\nmy second line" | interactive_command.sh # (Assuming a real terminal, it could be echo, echo -e, or printf to get the newline)
Or put the commands in a file and execute: interactive_command.sh < file_with_commands_to_input_on_multiple_lines

There are some circumstances where these techniques might not work; for example when a script goes out of its way to clear all things in the buffer before prompting or when the script attempts to do direct raw character reading. But those kinds of scripts seem rather rare.

Regardless though I'm pleased to hear you got a solution that worked for you!
May 27, 2015 at 2:35 PM
21region wrote:
We have solved our local problem (as far as I understand, it is not a general solution) by adding into source code overloaded version of RunCommand(, Action<> InteractiveResponse). We have found that, when an interactive program asks for input (even if the prompt is empty) SshCommand's method Channel_DataReceived() gets fired. When this happens, we immediately ::SendData(...). These data are then pushed by sshd into remote program's stdin. It seems that these follow up messages do not violate any RFC.
Hi, any chance you can include a code sample?