准备目标登录主机信息:
public class DestHost {
private String host = "";
private String username = "";
private String password = "";
private int port = 22;
private int timeout = 60 * 60 * 1000;
public DestHost(String host, String username, String password){
this(host, username, password, 22, 60*60*1000);
}
public DestHost(String host, String username, String password, int timeout){
this(host, username, password, 22, timeout);
}
public DestHost(String host, String username, String password, int port,
int timeout) {
super();
this.host = host;
this.username = username;
this.password = password;
this.port = port;
this.timeout = timeout;
}
...
}
SSH工具类:
1.JSch 使用shell执行命令,有两种方法:
ChannelExec channelExec = (ChannelExec) session.openChannel("exec");//只能执行一条指令(也可执行符合指令)
一次性执行多条shell的方法:
1)每个命令之间用;隔开
说明:各命令的执行给果,不会影响其它命令的执行。换句话说,各个命令都会执行,但不保证每个命令都执行成功。
2)每个命令之间用&&隔开
说明:若前面的命令执行成功,才会去执行后面的命令。这样可以保证所有的命令执行完毕后,执行过程都是成功的。
3)每个命令之间用||隔开
说明:||是或的意思,只有前面的命令执行失败后才去执行下一条命令,直到执行成功一条命令为止。
ChannelShell channelShell = (ChannelShell) session.openChannel("shell");//可执行多条指令 不过需要输入输出流
public class SSHUtils {
private static final String ENCODING = "UTF-8";
public static Session getJSchSession(DestHost destHost) throws JSchException {
JSch jsch = new JSch();
Session session = jsch.getSession(destHost.getUsername(), destHost.getHost(), destHost.getPort());
session.setPassword(destHost.getPassword());
session.setConfig("StrictHostKeyChecking", "no");//第一次访问服务器不用输入yes
session.setTimeout(destHost.getTimeout());
session.connect();
return session;
}
public static String execCommandByJSch(Session session, String command, String resultEncoding) throws IOException,JSchException{
//1.默认方式,执行单句命令
ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
InputStream in = channelExec.getInputStream();
channelExec.setCommand(command);
channelExec.setErrStream(System.err);
channelExec.connect();
String result = IOUtils.toString(in, resultEncoding);
channelExec.disconnect();
return result;
}
下面就是使用“shell”方式进行的调用:
public static String execCommandByShell(Session session)throws IOException,JSchException{
String result = "";
//2.尝试解决 远程ssh只能执行一句命令的情况
ChannelShell channelShell = (ChannelShell) session.openChannel("shell");
InputStream inputStream = channelShell.getInputStream();//从远端到达的数据 都能从这个流读取到
channelShell.setPty(true);
channelShell.connect();
OutputStream outputStream = channelShell.getOutputStream();//写入该流的数据 都将发送到远程端
//使用PrintWriter 就是为了使用println 这个方法
//好处就是不需要每次手动给字符加\n
PrintWriter printWriter = new PrintWriter(outputStream);
printWriter.println("cd /opt/applog/MSISVCServer");
printWriter.println("ls");
printWriter.println("exit");//为了结束本次交互
printWriter.flush();//把缓冲区的数据强行输出
/**
shell管道本身就是交互模式的。要想停止,有两种方式:
一、人为的发送一个exit命令,告诉程序本次交互结束
二、使用字节流中的available方法,来获取数据的总大小,然后循环去读。
为了避免阻塞
*/
byte[] tmp = new byte[1024];
while(true){
while(inputStream.available() > 0){
int i = inputStream.read(tmp, 0, 1024);
if(i < 0) break;
String s = new String(tmp, 0, i);
if(s.indexOf("--More--") >= 0){
outputStream.write((" ").getBytes());
outputStream.flush();
}
System.out.println(s);
}
if(channelShell.isClosed()){
System.out.println("exit-status:"+channelShell.getExitStatus());
break;
}
try{Thread.sleep(1000);}catch(Exception e){}
}
outputStream.close();
inputStream.close();
channelShell.disconnect();
session.disconnect();
System.out.println("DONE");
return result;
}