Java通过SSH2协议执行远程Shell脚本(ganymed-ssh2-build210.jar)
该工具Jar包可在:http://www.ganymed.ethz.ch/ssh2/下载ganymed-ssh2简介:
Ganymed SSH-2 for Java是用纯Java实现SSH-2协议的一个包。在使用它的过程中非常容易,只需要指定合法的用户名口令,
或者授权认证文件,就可以创建到远程Linux主机的连接,在建立起来的会话中调用该Linux主机上的脚本文件,执行相关操作。
使用方法:将 ganymed-ssh2-build210.jar 加入到项目的lib中。
使用步骤如下:
1.导包
官网下载:
http://www.ganymed.ethz.ch/ssh2/
maven坐标:
- <dependency>
- <groupId>com.ganymed.ssh2</groupId>
- <artifactId>ganymed-ssh2-build</artifactId>
- <version>210</version>
- </dependency>
2.apI说明
1. 首先构造一个连接器,传入一个需要登陆的ip地址
Connection conn = new Connection(hostname);
2. 模拟登陆目的服务器 传入用户名和密码 ,
boolean isAuthenticated = conn.authenticateWithPassword(username, password);它会返回一个布尔值,true 代表成功登陆目的服务器,否则登陆失败
3. 打开一个session,有点象Hibernate的session ,执行你需要的linux 脚本命令 。
Session sess = conn.openSession();
sess.execCommand("last");
4. 接收目标服务器上的控制台返回结果,读取br中的内容
InputStream stdout = new StreamGobbler(sess.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
5.得到脚本运行成功与否的标志 :0-成功 非0-失败
System.out.println("ExitCode: " + sess.getExitStatus());
6.关闭session和connection
sess.close();
conn.close();
备注:
1.通过第2步认证成功后,当前目录就位于/home/username/目录之下,你可以指定脚本文件所在的绝对路径,或者通过cd导航到脚本文件所在的目录,然后传递执行脚本所需要的参数,完成脚本调用执行。
2.执行脚本以后,可以获取脚本执行的结果文本,需要对这些文本进行正确编码后返回给客户端,避免乱码产生。
3.如果你需要执行多个linux控制台脚本,比如第一个脚本的返回结果是第二个脚本的入参,你必须打开多个Session,也就是多次调用
Session sess = conn.openSession();,使用完毕记得关闭就可以了
3.实例代码,这个类可以直接拷贝过去用
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.UnsupportedEncodingException;
- import org.apache.commons.lang.StringUtils;
- import ch.ethz.ssh2.Connection;
- import ch.ethz.ssh2.Session;
- import ch.ethz.ssh2.StreamGobbler;
- /**
- * 远程执行linux的shell script
- * @author Ickes
- * @since V0.1
- */
- public class RemoteExecuteCommand {
- //字符编码默认是utf-8
- private static String DEFAULTCHART="UTF-8";
- private Connection conn;
- private String ip;
- private String userName;
- private String userPwd;
- public RemoteExecuteCommand(String ip, String userName, String userPwd) {
- this.ip = ip;
- this.userName = userName;
- this.userPwd = userPwd;
- }
- public RemoteExecuteCommand() {
- }
- /**
- * 远程登录linux的主机
- * @author Ickes
- * @since V0.1
- * @return
- * 登录成功返回true,否则返回false
- */
- public Boolean login(){
- boolean flg=false;
- try {
- conn = new Connection(ip);
- conn.connect();//连接
- flg=conn.authenticateWithPassword(userName, userPwd);//认证
- } catch (IOException e) {
- e.printStackTrace();
- }
- return flg;
- }
- /**
- * @author Ickes
- * 远程执行shll脚本或者命令
- * @param cmd
- * 即将执行的命令
- * @return
- * 命令执行完后返回的结果值
- * @since V0.1
- */
- public String execute(String cmd){
- String result="";
- try {
- if(login()){
- Session session= conn.openSession();//打开一个会话
- session.execCommand(cmd);//执行命令
- result=processStdout(session.getStdout(),DEFAULTCHART);
- //如果为得到标准输出为空,说明脚本执行出错了
- if(StringUtils.isBlank(result)){
- result=processStdout(session.getStderr(),DEFAULTCHART);
- }
- conn.close();
- session.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return result;
- }
- /**
- * @author Ickes
- * 远程执行shll脚本或者命令
- * @param cmd
- * 即将执行的命令
- * @return
- * 命令执行成功后返回的结果值,如果命令执行失败,返回空字符串,不是null
- * @since V0.1
- */
- public String executeSuccess(String cmd){
- String result="";
- try {
- if(login()){
- Session session= conn.openSession();//打开一个会话
- session.execCommand(cmd);//执行命令
- result=processStdout(session.getStdout(),DEFAULTCHART);
- conn.close();
- session.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return result;
- }
- /**
- * 解析脚本执行返回的结果集
- * @author Ickes
- * @param in 输入流对象
- * @param charset 编码
- * @since V0.1
- * @return
- * 以纯文本的格式返回
- */
- private String processStdout(InputStream in, String charset){
- InputStream stdout = new StreamGobbler(in);
- StringBuffer buffer = new StringBuffer();;
- try {
- BufferedReader br = new BufferedReader(new InputStreamReader(stdout,charset));
- String line=null;
- while((line=br.readLine()) != null){
- buffer.append(line+"\n");
- }
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return buffer.toString();
- }
- public static void setCharset(String charset) {
- DEFAULTCHART = charset;
- }
- public Connection getConn() {
- return conn;
- }
- public void setConn(Connection conn) {
- this.conn = conn;
- }
- public String getIp() {
- return ip;
- }
- public void setIp(String ip) {
- this.ip = ip;
- }
- public String getUserName() {
- return userName;
- }
- public void setUserName(String userName) {
- this.userName = userName;
- }
- public String getUserPwd() {
- return userPwd;
- }
- public void setUserPwd(String userPwd) {
- this.userPwd = userPwd;
- }
- }
测试代码:
- public static void main(String[] args) {
- RemoteExecuteCommand rec=new RemoteExecuteCommand("192.168.238.133", "root","ickes");
- //执行命令
- System.out.println(rec.execute("ifconfig"));
- //执行脚本
- rec.execute("sh /usr/local/tomcat/bin/statup.sh");
- //这个方法与上面最大的区别就是,上面的方法,不管执行成功与否都返回,
- //这个方法呢,如果命令或者脚本执行错误将返回空字符串
- rec.executeSuccess("ifconfig");
- }
需要导入的包:
- <dependency>
- <groupId>com.ganymed.ssh2</groupId>
- <artifactId>ganymed-ssh2-build</artifactId>
- <version>210</version>
- </dependency>
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- <version>2.4</version>
- <type>jar</type>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.6</version>
- <type>jar</type>
- <scope>compile</scope>
- </dependency>