zoukankan      html  css  js  c++  java
  • 【原】Java程序调用远程Shell脚本

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

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

    【具体步骤】
    1、在远程机器上,准备Shell脚本。
    [root@localhost IFileGenTool]# vim ./load_data.sh

    1 #!/bin/sh
    2 source /etc/profile
    3 dbName=$1
    4 tableName=$2
    5 echo [`date +'%Y-%m-%d %H:%M:%S'`]' start loading data...'
    6 mysql -uroot -p123456 -P3306 ${dbName} -e "LOAD DATA LOCAL INFILE '/home/IFileGenTool/bak_data/bak_data_bak.txt' INTO TABLE ${tableName} FIELDS TERMINATED BY ';'"
    7 echo [`date +'%Y-%m-%d %H:%M:%S'`]' end loading data...'
    8 exit
    9 EOF

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

    1 <dependency>
    2     <groupId>org.jvnet.hudson</groupId>
    3     <artifactId>ganymed-ssh2</artifactId>
    4     <version>build210-hudson-1</version>
    5 </dependency>


    3、编写RemoteShellExecutor工具类。

      1 import java.io.IOException;
      2 import java.io.InputStream;
      3 import java.io.UnsupportedEncodingException;
      4 import java.nio.charset.Charset;
      5 
      6 import org.apache.commons.io.IOUtils;
      7 
      8 import ch.ethz.ssh2.ChannelCondition;
      9 import ch.ethz.ssh2.Connection;
     10 import ch.ethz.ssh2.Session;
     11 import ch.ethz.ssh2.StreamGobbler;
     12 
     13 public class RemoteShellExecutor {
     14      
     15      private Connection conn;
     16      /** 远程机器IP */
     17      private String ip;
     18      /** 用户名 */
     19      private String osUsername;
     20      /** 密码 */
     21      private String password;
     22      private String charset = Charset.defaultCharset().toString();
     23 
     24      private static final int TIME_OUT = 1000 * 5 * 60;
     25 
     26      /**
     27       * 构造函数
     28       * @param ip
     29       * @param usr
     30       * @param pasword
     31       */
     32      public RemoteShellExecutor(String ip, String usr, String pasword) {
     33           this.ip = ip;
     34          this.osUsername = usr;
     35          this.password = pasword;
     36      }
     37 
     38 
     39      /**
     40      * 登录
     41      * @return
     42      * @throws IOException
     43      */
     44      private boolean login() throws IOException {
     45          conn = new Connection(ip);
     46          conn.connect();
     47          return conn.authenticateWithPassword(osUsername, password);
     48      }
     49 
     50      /**
     51      * 执行脚本
     52      * 
     53      * @param cmds
     54      * @return
     55      * @throws Exception
     56      */
     57      public int exec(String cmds) throws Exception {
     58          InputStream stdOut = null;
     59          InputStream stdErr = null;
     60          String outStr = "";
     61          String outErr = "";
     62          int ret = -1;
     63          try {
     64          if (login()) {
     65              // Open a new {@link Session} on this connection
     66              Session session = conn.openSession();
     67              // Execute a command on the remote machine.
     68              session.execCommand(cmds);
     69              
     70              stdOut = new StreamGobbler(session.getStdout());
     71              outStr = processStream(stdOut, charset);
     72              
     73              stdErr = new StreamGobbler(session.getStderr());
     74              outErr = processStream(stdErr, charset);
     75              
     76              session.waitForCondition(ChannelCondition.EXIT_STATUS, TIME_OUT);
     77              
     78              System.out.println("outStr=" + outStr);
     79              System.out.println("outErr=" + outErr);
     80              
     81              ret = session.getExitStatus();
     82          } else {
     83              throw new Exception("登录远程机器失败" + ip); // 自定义异常类 实现略
     84          }
     85          } finally {
     86              if (conn != null) {
     87                  conn.close();
     88              }
     89              IOUtils.closeQuietly(stdOut);
     90              IOUtils.closeQuietly(stdErr);
     91          }
     92          return ret;
     93      }
     94 
     95      /**
     96      * @param in
     97      * @param charset
     98      * @return
     99      * @throws IOException
    100      * @throws UnsupportedEncodingException
    101      */
    102      private String processStream(InputStream in, String charset) throws Exception {
    103          byte[] buf = new byte[1024];
    104          StringBuilder sb = new StringBuilder();
    105          while (in.read(buf) != -1) {
    106              sb.append(new String(buf, charset));
    107          }
    108          return sb.toString();
    109      }
    110 
    111     public static void main(String args[]) throws Exception {
    112         RemoteShellExecutor executor = new RemoteShellExecutor("192.168.234.123", "root", "beebank");
    113         // 执行myTest.sh 参数为java Know dummy
    114         System.out.println(executor.exec("/home/IFileGenTool /load_data.sh t_users myDataBase01"));
    115     }
    116 }

    4、Java程序调用远程Shell

    private void backupAndRestoreData(String originalTableName) throws Exception {
        
        //1. 调用远程Shell脚本,对生产库中数据进行导出和导入备份。                
        LogUtil.getLogger().info("######    1. 开始对数据库中数据利用进行导出和导入备份   ######");
        RemoteShellExecutor executor = new RemoteShellExecutor("192.168.234.123", "root", "root");
        // 执行myTest.sh 参数为java Know dummy
        System.out.println(executor.exec("/home/IFileGenTool/load_data.sh"));
    }

    5、运行结果

    备份数据成功。

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

    注:一般情况下shell脚本正常执行完毕,getExitStatus方法返回0。
    此方法通过远程命令取得Exit Code/status。但并不是每个server设计时都会返回这个值,如果没有则会返回null。
    在调用getExitStatus时,要先调用WaitForCondition方法,通过ChannelCondition.java接口的定义可以看到每个条件的具体含义。见以下代码:
    ChannelCondition.java的源代码

    参考连接:http://yu.you163.blog.163.com/blog/static/339877742012117101039968/

  • 相关阅读:
    MINIX文件系统
    Cmd Markdown 语法
    asp.net mvc 4 json大数据异常 提示JSON字符长度超出限制的异常[转载]
    echart 拖拽
    搭建django开发环境
    Django 1.11.7+django_pyodbc_azure-1.11.0.0+pyodbc 连接mssql 数据库
    二、PyCharm 创建Django 第一个项目
    一、Django 安装
    python 连接各类主流数据库简单示例【转载】
    Python 3.6 连接mssql数据库(pymssql 方式)
  • 原文地址:https://www.cnblogs.com/zjrodger/p/5551385.html
Copyright © 2011-2022 走看看