问题
I referred the question Multiple bash commands and implemented as below. I am connecting to a device for which first command should be configure
then only I will get a prompt to execute all other commands. I don't get output for any of the commands and the control does not return.
The following are the commands that work in terminal.
ssh uname@ip
configure # this command changes prompt and enable following commands
move shared pre-rulebase security rules TEST top
commit
exit
exit
As asked for, if I do this instead, after entering password the control doesn't return:
ssh user@host configure
The script
String[] commands = new String[]{
"configure", "move shared pre-rulebase security rules TEST top", "commit", "exit"};
FileWriter fileOut = new FileWriter(outFileName, true);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
JSch jsch = new JSch();
Session session = jsch.getSession(user, host, 22);
session.setPassword(password);
session.setConfig(config);
session.connect();
System.out.println("Connected");
System.out.println(commands[0]);
ChannelExec channel = (ChannelExec) session.openChannel("exec");
((ChannelExec) channel).setCommand(commands[0]);
channel.setInputStream(null);
((ChannelExec)channel).setErrStream(System.err);
InputStream in = channel.getInputStream();
outStream = channel.getOutputStream();
channel.connect();
Thread.sleep(1000);
for(int i=1;i<commands.length;i++) {
System.out.println("Executing:"+commands[i]);
outStream.write((commands[i]+"\n").getBytes());
outStream.flush();
}
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0)
break;
resultString = new String(tmp, 0, i);
fileOut.write(resultString);
}
if (channel.isClosed()) {
if(in.available()>0) continue;
System.out.println("exit-status: " + channel.getExitStatus());
break;
}
try {
Thread.sleep(1000);
} catch (Exception ee) {
}
}
channel.disconnect();
session.disconnect();
outStream.close();
fileOut.close();
回答1:
The "exec" channel on your device seems to be implemented incorrectly. So you cannot use your code with the "exec" channel. As you can to "ssh" to the device, it seems that the "shell" channel is fully working. Try talking to your server administrator, to get the server fixed.
If fixing the server is not feasible, you will have to revert to using the "shell" channel, although it is generally not the correct way to implement command automation.
See What is the difference between the 'shell' channel and the 'exec' channel in JSch
JSch by default enables terminal emulation for the "shell" channel, what will bring lot of unwanted side effects (see Getting unwanted characters when reading command output from SSH server using JSch). You may need to disable that by calling setPty.
ChannelShell channel = (ChannelShell) session.openChannel("shell");
InputStream in = channel.getInputStream();
outStream = channel.getOutputStream();
channel.setPty(false);
channel.connect();
outStream.write('configure\n'.getBytes());
outStream.write('move shared pre-rulebase security rules TEST top\n'.getBytes());
来源:https://stackoverflow.com/questions/56493882/executing-multiple-commands-over-ssh-exec-channel-on-firewall-device-with-java