此程序的目的是執行遠程機器上的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/