此程序的目的是执行远程机器上的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/