I want to check
exit command is executed success in a ssh session.
My first attempt is using the command:
exit && echo $? || echo $?`.The `echo $? || echo $?
it should print
0 if exit successful. The problem is
echo never executes if
exit execute success because connection is disconnected and the later command is lost.
My second attempt is splitting the command to two command, as this:
$ exit $ echo $?
echo $? should be
exit execute successful. But another problem is
echo $? maybe be swallowed because it send so quickly that arrived to the remote ssh host before
exit be executed.
So, how to ensure
exit is executed at remote host before send next command?
The using stage is I execute shell command at a program language and send message by a ssh pipe stream.So, I don't know the
exit command executed time.If the
exit command not completed, my follow commands will be swallowed because they send to the exiting host.
That is why I'm care about the
exit command executed.
1. Which stage I am encountered the problem?
At beginning, I want to describe the problem as simply as possible but it seems more confusing. I am writing a SSH library with Scala language at the git library.
It is not a interactive terminal. The response message from remote host is network IO stream, hold by the program, parse the result as String.That means, I must deal with every char codes and finally decide the command executed success or fail.
Some example code show as this:
//create a ssh by JSch library which is a SSH implement by Java Language. val shell = Shell(Auth("host", "username", 22, "mypassword")) //execute shell command as we do at terminal for example. val rst1 = shell.exc("ls") //create a new shell based on this shell. val newShell = shell.newShell(Auth("xxx.xxx.xxx.xxx", "username2", 22, "mypassword")) //do something on the new shell val rst2 = newShell.exc("touch somefile") //exit from new shell newShell.exit()
newShell is created by
sshpass -p 'password' ssh -T username@hostname as a normal command sent by
JSch, so it is not any magic. It just like sending a normal command, such as
The problem in the implement of the
exit() method, if we ignore Scala code, it become those shell command:
$ echo '' && echo 'some-splitter-string' && exit $ echo $? && echo 'some-splitter-string'
After sent that command to remote host what I expect response is this, but actually it not does, I'm explicitly append a
\n character for read straightly:
\n some-splitter-string\n 0\n some-splitter-string\n
That means, I can split the IO stream by double
some-splitter-string and get the inner
0(maybe others) to decide the
exit command execute completed, that is my protocol to decode a shell command result.
2. What is the problem exactly?
exit() command just response me:
The second command
echo $? && echo 'some-splitter-string' is lost! That is because the command
$ echo $? && echo 'some-splitter-string' also sent to the newShell host.
exit completed, this command is swallowed by the newShell host. Just consider this command simply
exit && touch somefile. The later
touch somefile never could be executed.
My current solution is sleep 1s after send
echo '' && echo 'some-splitter-string' && exit command, it should be more elegance. So I want to find a way to ensure
exit is executed and then I will send the second command to completed my protocol.
3. Some question to clarify:
How could the "execution" of exit fail?
Not exactly focus on fail or success at this point.That means, if
exitcan't be fail, just let me know it executed complete is ok.
Are we talking about a shell exit here?
Yes, The aim of the question is find a way to decide the exit command executed complete in a ssh pipe environment.