I've testing the performance difference of sending multiple commands using the Java JSch library using the "exec" and "shell" channels. What's I've found is that "exec" takes double the amount of time. I'm using, as an example, the command ls /etc/***, and sending it 10, 100, 500, and 1000 times. They all behave similarly, and the difference is sometimes up to 15 seconds.
I know I can send multiple commands in the form of cm1;cm2;cm3 etc, but it's not the test I want.
Has anyone had a similar experience using shell and exec?
I'm posting some of the code for both type of tests (part of this code comes from this same site written by others).
Using shell:
For the shell channel I send ls /etc/; echo "END_OF_COMMAND"
...
...
...
session = getSession (username, password, host);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream ();
ChannelShell channel = (ChannelShell) session.openChannel ("shell");
channel.setOutputStream (outputStream);
PrintStream stream = new PrintStream (channel.getOutputStream ());
channel.connect ();
for (int i = 0; i < trials; i++) {
System.out.println("Trial #" + i);
stream.println (cmd);
stream.flush ();
String output = getCmdOutput (outputStream);
}
channel.disconnect ();
session.disconnect ();
...
...
...
public static String getCmdOutput (ByteArrayOutputStream outputStream) throws InterruptedException {
while (outputStream.toString ().indexOf ("\nEND_OF_COMMAND") <= 0) {}
String output = outputStream.toString ();
outputStream.reset ();
return output;
}
Using exec:
...
...
...
for (int i = 0; i < trials; ++i) {
System.out.println("Trial #" + i);
execCmd(session, cmd);
}
...
...
...
public static void execCmd (Session session, String cmd) {
ChannelExec channel = null;
try {
channel = (ChannelExec) session.openChannel ("exec");
InputStream in = channel.getInputStream();
channel.setCommand (cmd);
channel.setPty(true);
channel.connect ();
String output = readOuput(in);
}
catch (Exception e) {
e.printStackTrace ();
}
finally {
if (channel != null && channel.isConnected ()) {
System.out.println("Channel Exit Code: " + channel.getExitStatus());
channel.disconnect ();
}
}
}
public static String readOuput (InputStream in) throws IOException {
StringBuilder sb = new StringBuilder ();
try (BufferedReader br = new BufferedReader(new InputStreamReader(new BufferedInputStream(in)))) {
String line;
while ((line = br.readLine ()) != null) {
sb.append (line + System.lineSeparator ());
}
}
return sb.toString ();
}