【原】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-build210\src下的代碼直接拷貝到我們的工程里,
此源碼的好處就是沒有依賴很多其他的包,拷貝過來干干凈凈。

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/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM