java调用远程机器的shell脚本

此程序的目的是执行远程机器上的Shell脚本。

【环境参数】
远程机器IP:192.168.174.129
用户名:root
密码:root
Shell脚本的路径:/root/test/test.sh

【具体步骤】
1、在远程机器上,准备Shell脚本。
2、修改test.sh的文件权限,确保可执行

3、开启远程机器的sshd的权限

步骤:

1、修改sshd_config文件,命令为:vi /etc/ssh/sshd_config 

2、将#PasswordAuthentication no的注释去掉,并且将NO修改为YES 

3、将#PermitRootLogin yes的注释去掉 

4、重新启动SSH服务,命令为:/etc/init.d/sshd restart 

5、验证SSH服务状态,命令为:/etc/init.d/sshd status 

 

若没有开启sshd服务,会提示以下这样的错误:

java.io.IOException: Password authentication failed. 
at ch.ethz.ssh2.auth.AuthenticationManager.authenticatePassword(AuthenticationManager.java:300) 
at ch.ethz.ssh2.Connection.authenticateWithPassword(Connection.java:309) 
at test.demo.TestSSH.main(TestSSH.java:19) 
Caused by: java.io.IOException: Authentication method password not supported by the server at this stage. 
at ch.ethz.ssh2.auth.AuthenticationManager.authenticatePassword(AuthenticationManager.java:270) 
... 2 more 

 
sh脚本内容:
 
echo [`date +'%Y-%m-%d %H:%M:%S'`]' start loading data...'
echo [`date +'%Y-%m-%d %H:%M:%S'`]' end loading data...'
exit
复制代码

 

2、导入需要依赖的jar包。
Java远程调用Shell脚本这个程序需要ganymed-ssh2-build210.jar包。
下载地址:http://www.ganymed.ethz.ch/ssh2/
为了调试方便,可以将\ganymed-ssh2-build210\src下的代码直接拷贝到我们的工程里,
此源码的好处就是没有依赖很多其他的包,拷贝过来干干净净。


3、java调用工具类:

package test;

 

 

import java.io.IOException;

import java.io.InputStream;

import java.io.UnsupportedEncodingException;

import java.nio.charset.Charset;

import org.apache.commons.io.IOUtils;

import ch.ethz.ssh2.ChannelCondition;

import ch.ethz.ssh2.Connection;

import ch.ethz.ssh2.Session;

import ch.ethz.ssh2.StreamGobbler;

 

public class RemoteShellExecutor {

     

     private Connection conn;

     /** 远程机器IP */

     private String ip;

     /** 用户名 */

     private String osUsername;

     /** 密码 */

     private String password;

     private String charset = Charset.defaultCharset().toString();

 

     private static final int TIME_OUT = 1000 * 5 * 60;

 

     /**

      * 构造函数

      * @param ip

      * @param usr

      * @param pasword

      */

     public RemoteShellExecutor(String ip, String usr, String pasword) {

          this.ip = ip;

         this.osUsername = usr;

         this.password = pasword;

     }

 

 

     /**

     * 登录

     * @return

     * @throws IOException

     */

     private boolean login() throws IOException {

         conn = new Connection(ip);

         conn.connect();

         return conn.authenticateWithPassword(osUsername, password);

     }

 

     /**

     * 执行脚本

     * 

     * @param cmds

     * @return

     * @throws Exception

     */

     public int exec(String cmds) throws Exception {

         InputStream stdOut = null;

         InputStream stdErr = null;

         String outStr = "";

         String outErr = "";

         int ret = -1;

         try {

         if (login()) {

             // Open a new {@link Session} on this connection

             Session session = conn.openSession();

             // Execute a command on the remote machine.

             session.execCommand(cmds);

             

             stdOut = new StreamGobbler(session.getStdout());

             outStr = processStream(stdOut, charset);

             

             stdErr = new StreamGobbler(session.getStderr());

             outErr = processStream(stdErr, charset);

             

             session.waitForCondition(ChannelCondition.EXIT_STATUS, TIME_OUT);

             

             System.out.println("outStr=" + outStr);

             System.out.println("outErr=" + outErr);

             

             ret = session.getExitStatus();

         } else {

             throw new Exception("登录远程机器失败" + ip); // 自定义异常类 实现略

         }

         } finally {

             if (conn != null) {

                 conn.close();

             }

             IOUtils.closeQuietly(stdOut);

             IOUtils.closeQuietly(stdErr);

         }

         return ret;

     }

 

     /**

     * @param in

     * @param charset

     * @return

     * @throws IOException

     * @throws UnsupportedEncodingException

     */

     private String processStream(InputStream in, String charset) throws Exception {

         byte[] buf = new byte[1024];

         StringBuilder sb = new StringBuilder();

         while (in.read(buf) != -1) {

             sb.append(new String(buf, charset));

         }

         return sb.toString();

     }

 

    public static void main(String args[]) throws Exception {

        RemoteShellExecutor executor = new RemoteShellExecutor("192.168.174.128", "root", "root");

     

        executor.exec("chmod 740 /root/test/test.sh");

        System.out.println(executor.exec("/root/test/test.sh t_users myDataBase01"));

    }

}

 

 

 

5、运行结果

outStr=

outErr=

outStr=[2017-07-14 00:12:47] start loading data...

2017-07-14 00:12:47] end loading data...

 

6、说明:
0 // getExitStatus方法的返回值

注:一般情况下shell脚本正常执行完毕,getExitStatus方法返回0。
此方法通过远程命令取得Exit Code/status。但并不是每个server设计时都会返回这个值,如果没有则会返回null。
在调用getExitStatus时,要先调用WaitForCondition方法

猜你喜欢

转载自zengshaotao.iteye.com/blog/2384448