This is a POC for an interactive Shell client in SSHJ.
It is not intended as an example of 'Best Practice' - in fact, quite the contrary.
It is a solution that I have found, and would welcome any input on if / how it could be improved.
Note that this code is Windows specific - as in, it is only designed for SSHing into a Windows machine.
To make it OS agnostic, one would need to modify the prompt detection and the ErrorLevel handling (Maybe also the line endings too?)
My use-case is automated testing. I wish to run numerous SSH commands on a remote machine, and some of these commands depend on previous commands,
some of which are long-running. As such, chaining multiple commands together (eg using &&) is not optimal.
A session is opened in Shell mode - the implication of this seem to be that calling readAllBytes() on the InputStream, or using read() in a loop and waiting for it to return -1 will not work (The stream never "ends" per se as it is a shell).
Therefore, in order to detect "End" of each command, it parses StdIn and looks for a command prompt (eg C:\Users\Administrator>).
As such, the "Current directory" is stored as part of the class, so you don't have to endlessly supply the expected prompt.
A special changeFolder() method is provided to change the current folder.
When a command is issued, the number of characters present in the command is read from the InputStream, to keep it out of the response.
StdErr is then checked for any output, and if found, is packaged into the response.
StdIn is then read, even if there is an error, because the new prompt would still be present in the InputStream.
If there was an error, an echo %ERRORLEVEL% is then issued, and the ErrorLevel of the last command is parsed from StdIn and packaged into the response.
- For some reason, sometimes it takes a while to initialize the Client - ie
new SSHClient()sometimes hangs for quite a long time. - Is some kind of cleanup needed? I have looked at process manager on the remote machine, and if I terminate the code before
close()gets called, the SSH process still seems to end. However, I suspect not doing this is what may be causing (1)?
========================================
COMMAND: dir
STDOUT:
Volume in drive C has no label.
Volume Serial Number is 4431-6939
Directory of C:\Users\Administrator
10/09/2025 22:11 <DIR> .
10/09/2025 21:25 <DIR> ..
10/09/2025 21:25 <DIR> Contacts
18/09/2025 23:02 <DIR> Desktop
10/09/2025 21:25 <DIR> Documents
10/09/2025 21:25 <DIR> Downloads
10/09/2025 21:25 <DIR> Favorites
10/09/2025 21:25 <DIR> Links
10/09/2025 21:25 <DIR> Music
10/09/2025 21:25 <DIR> Pictures
10/09/2025 21:25 <DIR> Saved Games
10/09/2025 21:25 <DIR> Searches
10/09/2025 21:25 <DIR> Videos
0 File(s) 0 bytes
13 Dir(s) 80,608,309,248 bytes free
----------------------------------------
ERRORLEVEL: 0
========================================
Changing folder to: C:\tmp
========================================
COMMAND: dir
STDOUT:
Volume in drive C has no label.
Volume Serial Number is 4431-6939
Directory of C:\tmp
19/09/2025 15:10 <DIR> .
19/09/2025 15:10 0 File1.txt
19/09/2025 15:10 0 File2.txt
2 File(s) 0 bytes
1 Dir(s) 80,608,309,248 bytes free
----------------------------------------
ERRORLEVEL: 0
========================================
COMMAND: foo
STDOUT:
----------------------------------------
ERRORLEVEL: 9009
STDERR:
'foo' is not recognized as an internal or external command,
operable program or batch file.