问题
I am using JSch to connect to SSH and execute commands. One of the commands gives out a big output. In terminal if you execute the command you have to press enter to see the entire output. Using JSch I am not able to retrieve the entire output.
When I login using an interactive terminal, the command output stops after filling a screen and waits for Enter.
The code is taken from How to get jsch shell command output in String:
public class SshConnectionManager {
private static Session session;
private static ChannelShell channel;
private static String username = "";
private static String password = "";
private static String hostname = "";
private static Session getSession(){
if(session == null || !session.isConnected()){
session = connect(hostname,username,password);
}
return session;
}
private static Channel getChannel(){
if(channel == null || !channel.isConnected()){
try{
channel = (ChannelShell)getSession().openChannel("shell");
channel.connect();
}catch(Exception e){
System.out.println("Error while opening channel: "+ e);
}
}
return channel;
}
private static Session connect(String hostname, String username, String password){
JSch jSch = new JSch();
try {
session = jSch.getSession(username, hostname, 22);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setPassword(password);
System.out.println("Connecting SSH to " + hostname + " - Please wait for few seconds... ");
session.connect();
System.out.println("Connected!");
}catch(Exception e){
System.out.println("An error occurred while connecting to "+hostname+": "+e);
}
return session;
}
private static void executeCommands(List<String> commands){
try{
Channel channel=getChannel();
System.out.println("Sending commands...");
sendCommands(channel, commands);
readChannelOutput(channel);
System.out.println("Finished sending commands!");
}catch(Exception e){
System.out.println("An error ocurred during executeCommands: "+e);
}
}
private static void sendCommands(Channel channel, List<String> commands){
try{
PrintStream out = new PrintStream(channel.getOutputStream());
out.println("#!/bin/bash");
for(String command : commands){
out.println(command);
}
out.println("exit");
out.flush();
}catch(Exception e){
System.out.println("Error while sending commands: "+ e);
}
}
private static void readChannelOutput(Channel channel){
byte[] buffer = new byte[1024];
try{
InputStream in = channel.getInputStream();
String line = "";
while (true){
while (in.available() > 0) {
int i = in.read(buffer, 0, 1024);
if (i < 0) {
break;
}
line = new String(buffer, 0, i);
System.out.println(line);
}
if(line.contains("logout")){
break;
}
if (channel.isClosed()){
break;
}
try {
Thread.sleep(1000);
} catch (Exception ee){}
}
}catch(Exception e){
System.out.println("Error while reading channel output: "+ e);
}
}
public static void close(){
channel.disconnect();
session.disconnect();
System.out.println("Disconnected channel and session");
}
public static void main(String[] args){
List<String> commands = new ArrayList<String>();
commands.add("ls -l");
executeCommands(commands);
close();
}
}
回答1:
You generally should not use "shell" channel to automate a command execution.
The "shell" channel is intended to implement an interactive shell session.
Hence it requests PTY (pseudo-terminal), which has human-friendly, but machine-unfriendly, side-effects that break your code.
Use "exec" channel instead.
See Execute a list of commands from an ArrayList using JSch exec in Java
If you need or want to use the "shell" channel for some reason (but do not, it will bite you anyway), make sure you call .setPty(false)
before .connect
:
channel = (ChannelShell)getSession().openChannel("shell");
channel.setPty(false);
channel.connect();
Side notes:
- The
"#!/bin/bash"
is a pure nonsense. The shell ignores all commands starting with#
(it's comment). There's no point sending it. - Do not use
StrictHostKeyChecking=no
. See JSch SFTP security with session.setConfig(“StrictHostKeyChecking”, “no”);.
来源:https://stackoverflow.com/questions/35502600/jsch-issue-cannot-retrieve-full-command-output