您的位置:首页 > 运维架构 > Shell

Java程序调用远程Shell脚本

2017-10-13 14:12 567 查看
此程序的目的是执行远程机器上的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的源代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: