So, here's the situation:
I would like to use the sshj library to connect to a host which automatically runs a script on connection. Let's say the script merely logs whatever json formated input it receives. In the terminal I can run something like:
echo '{ "name" : "Hubert", "status" : "alive" }' | ssh -i ~/.ssh/id_ed25519 user@host.com
and upon connection the host would log the info { "name" : "Hubert", "status" : "alive" }.
What would an (equivalent) implementation of the above command look like in sshj?
Okay, I am not 100% sure whether all I do in the following code is entirely necessary, but it works for me:
final SSHClient ssh = new SSHClient();
/*
* Connect to host and authenticate
*/
try (Session session = ssh.startSession()){
// open a shell on host
final Shell shl = session.startShell();
// just a thread to stream stdout of host
Thread t = new Thread() {
@Override
public void run() {
try {
InputStream in = shl.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = br.readLine()) != null) {
System.out.println("## " + line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
t.start();
// another thread to stream stderr of host
Thread err_t = new Thread() {
@Override
public void run() {
try {
InputStream in = shl.getErrorStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = br.readLine()) != null) {
System.out.println("## " + line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
err_t.start();
// you might want to escape the input string
String input = "Some String";
byte[] data = input.getBytes();
// getOutputStream() corresponds to the hosts stdin
OutputStream out = shl.getOutputStream();
out.write(data);
// ensure all written bytes get flushed to host
out.flush();
out.close();
shl.join(5, TimeUnit.SECONDS);
shl.close();
} finally {
ssh.disconnect();
}