Java SSH远程执行Shell脚本实现
2013-03-14 14:38
721 查看
此程序需要ganymed-ssh2-build210.jar包。
下载地址:http://www.ganymed.ethz.ch/ssh2/
为了调试方便,可以将\ganymed-ssh2-build210\src下的代码直接拷贝到我们的工程里,
此源码的好处就是没有依赖很多其他的包,拷贝过来干干净净。
此程序的目的是执行远程机器上的Shell脚本。
远程机器IP:***.**.**.***
用户名:sshapp
密码:sshapp
登录后用pwd命令,显示当前目录为:/sshapp.
在/sshapp/myshell/目录下有myTest.sh文件,内容如下:
echo $1 $2 $#
#print $1
我们的Java代码RmtShellExecutor.java:
执行后结果:
outStr=java Know 3
outErr=
0 // getExitStatus方法的返回值
注:一般情况下shell脚本正常执行完毕,getExitStatus方法返回0。
此方法通过远程命令取得Exit Code/status。但并不是每个server设计时都会返回这个值,如果没有则会返回null。
在调用getExitStatus时,要先调用WaitForCondition方法,通过ChannelCondition.java接口的定义可以看到每个条件的具体含义。见以下代码:
ChannelCondition.java
当我们把myTest.sh修改为如下内容:
echo $1 $2 $#
print $1
由于我使用的linux机器上没有print命令,所以print $1会报错:command not found。
接下来再让我们执行一下,看看控制台的结果:
outStr=java Know 3
outErr=/sshapp/myshell/myTest.sh: line 2: print: command not found
127
此时shell脚本出现错误,getExitStatus方法返回127.
在实际应用中,可以将outStr和outErr记录到日志中,以便维护人员查看shell的执行情况,
而getExitStatus的返回值,可以认为是此次执行是否OK的标准。
下载地址:http://www.ganymed.ethz.ch/ssh2/
为了调试方便,可以将\ganymed-ssh2-build210\src下的代码直接拷贝到我们的工程里,
此源码的好处就是没有依赖很多其他的包,拷贝过来干干净净。
此程序的目的是执行远程机器上的Shell脚本。
远程机器IP:***.**.**.***
用户名:sshapp
密码:sshapp
登录后用pwd命令,显示当前目录为:/sshapp.
在/sshapp/myshell/目录下有myTest.sh文件,内容如下:
echo $1 $2 $#
#print $1
我们的Java代码RmtShellExecutor.java:
/** *//** * 远程执行shell脚本类 * @author l */ public class RmtShellExecutor { /** *//** */ private Connection conn; /** *//** 远程机器IP */ private String ip; /** *//** 用户名 */ private String usr; /** *//** 密码 */ private String psword; private String charset = Charset.defaultCharset().toString(); private static final int TIME_OUT = 1000 * 5 * 60; /** *//** * 构造函数 * @param param 传入参数Bean 一些属性的getter setter 实现略 */ public RmtShellExecutor(ShellParam param) { this.ip = param.getIp(); this.usr = param.getUsername(); this.psword = param.getPassword(); } /** *//** * 构造函数 * @param ip * @param usr * @param ps */ public RmtShellExecutor(String ip, String usr, String ps) { this.ip = ip; this.usr = usr; this.psword = ps; } /** *//** * 登录 * * @return * @throws IOException */ private boolean login() throws IOException { conn = new Connection(ip); conn.connect(); return conn.authenticateWithPassword(usr, psword); } /** *//** * 执行脚本 * * @param cmds * @return * @throws Exception */ public int exec(String cmds) throws Exception { InputStream stdOut = null; InputStream stdErr = null; String outStr = ""; String outErr = ""; int ret = -1; try { if (login()) { // Open a new {@link Session} on this connection Session session = conn.openSession(); // Execute a command on the remote machine. session.execCommand(cmds); stdOut = new StreamGobbler(session.getStdout()); outStr = processStream(stdOut, charset); stdErr = new StreamGobbler(session.getStderr()); outErr = processStream(stdErr, charset); session.waitForCondition(ChannelCondition.EXIT_STATUS, TIME_OUT); System.out.println("outStr=" + outStr); System.out.println("outErr=" + outErr); ret = session.getExitStatus(); } else { throw new AppException("登录远程机器失败" + ip); // 自定义异常类 实现略 } } finally { if (conn != null) { conn.close(); } IOUtils.closeQuietly(stdOut); IOUtils.closeQuietly(stdErr); } return ret; } /** *//** * @param in * @param charset * @return * @throws IOException * @throws UnsupportedEncodingException */ private String processStream(InputStream in, String charset) throws Exception { byte[] buf = new byte[1024]; StringBuilder sb = new StringBuilder(); while (in.read(buf) != -1) { sb.append(new String(buf, charset)); } return sb.toString(); } public static void main(String args[]) throws Exception { RmtShellExecutor exe = new RmtShellExecutor("***.**.**.***", "sshapp", "sshapp"); // 执行myTest.sh 参数为java Know dummy System.out.println(exe.exec("sh /webapp/myshell/myTest.sh java Know dummy")); // exe.exec("uname -a && date && uptime && who"); } }
执行后结果:
outStr=java Know 3
outErr=
0 // getExitStatus方法的返回值
注:一般情况下shell脚本正常执行完毕,getExitStatus方法返回0。
此方法通过远程命令取得Exit Code/status。但并不是每个server设计时都会返回这个值,如果没有则会返回null。
在调用getExitStatus时,要先调用WaitForCondition方法,通过ChannelCondition.java接口的定义可以看到每个条件的具体含义。见以下代码:
ChannelCondition.java
package ch.ethz.ssh2; /** *//** * Contains constants that can be used to specify what conditions to wait for on * a SSH-2 channel (e.g., represented by a {@link Session}). * * @see Session#waitForCondition(int, long) * * @author Christian Plattner, plattner@inf.ethz.ch * @version $Id: ChannelCondition.java,v 1.6 2006/08/11 12:24:00 cplattne Exp $ */ public abstract interface ChannelCondition { /** *//** * A timeout has occurred, none of your requested conditions is fulfilled. * However, other conditions may be true - therefore, NEVER use the "==" * operator to test for this (or any other) condition. Always use * something like <code>((cond & ChannelCondition.CLOSED) != 0)</code>. */ public static final int TIMEOUT = 1; /** *//** * The underlying SSH-2 channel, however not necessarily the whole connection, * has been closed. This implies <code>EOF</code>. Note that there may still * be unread stdout or stderr data in the local window, i.e, <code>STDOUT_DATA</code> * or/and <code>STDERR_DATA</code> may be set at the same time. */ public static final int CLOSED = 2; /** *//** * There is stdout data available that is ready to be consumed. */ public static final int STDOUT_DATA = 4; /** *//** * There is stderr data available that is ready to be consumed. */ public static final int STDERR_DATA = 8; /** *//** * EOF on has been reached, no more _new_ stdout or stderr data will arrive * from the remote server. However, there may be unread stdout or stderr * data, i.e, <code>STDOUT_DATA</code> or/and <code>STDERR_DATA</code> * may be set at the same time. */ public static final int EOF = 16; /** *//** * The exit status of the remote process is available. * Some servers never send the exist status, or occasionally "forget" to do so. */ public static final int EXIT_STATUS = 32; /** *//** * The exit signal of the remote process is available. */ public static final int EXIT_SIGNAL = 64; }
当我们把myTest.sh修改为如下内容:
echo $1 $2 $#
print $1
由于我使用的linux机器上没有print命令,所以print $1会报错:command not found。
接下来再让我们执行一下,看看控制台的结果:
outStr=java Know 3
outErr=/sshapp/myshell/myTest.sh: line 2: print: command not found
127
此时shell脚本出现错误,getExitStatus方法返回127.
在实际应用中,可以将outStr和outErr记录到日志中,以便维护人员查看shell的执行情况,
而getExitStatus的返回值,可以认为是此次执行是否OK的标准。
相关文章推荐
- Java SSH远程执行Shell脚本实现
- Java实现远程ssh执行shell脚本对文件打包下载
- Java SSH远程执行Shell脚本实现
- Java SSH远程执行Shell脚本实现
- Java SSH远程执行Shell脚本实现
- Java SSH远程执行Shell脚本实现(转)
- Java SSH远程执行Shell脚本实现
- Java SSH远程执行Shell脚本实现
- Java SSH远程执行Shell脚本实现(转)
- Java实践 — SSH远程执行Shell脚本
- Java实践 — SSH远程执行Shell脚本
- Java程序SSH远程执行Shell脚本
- Java实践 — SSH远程执行Shell脚本
- Java实践 — SSH远程执行Shell脚本(转)
- ssh远程执行命令方法和Shell脚本实例
- 使用shell脚本ssh远程执行命令,使用awk时总是报错
- 纯JAVA实现远程执行SSH2主机的SHELL命令
- ssh远程执行shell脚本结束之后不能自动退出
- Window下Java远程调用Shell脚本的实现(学习整理)
- Java通过SSH2协议执行远程Shell脚本(ganymed-ssh2-build210.jar)