java ssh 远程执行_Java SSH远程执行Shell脚本实现(转)

Java SSH远程执行Shell脚本实现(转)

[JSch:纯JAVA实现远程执行SSH2主机的SHELL命令]

Java SSH远程执行Shell脚本实现

此程序需要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:

/** *//**

* 远程执行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方法,[1.首先下载ganymed-ssh2.jar   http://www.ganymed.ethz.ch/ssh22.SSHUtil工具类import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;通过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 ((cond & ChannelCondition.CLOSED) != 0).

*/

public static final int TIMEOUT = 1;

/** *//**

* The underlying SSH-2 channel, however not necessarily the whole connection,

* has been closed. This implies EOF. Note that there may still

* be unread stdout or stderr data in the local window, i.e, STDOUT_DATA

* or/and STDERR_DATA 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, STDOUT_DATA or/and STDERR_DATA

* 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的标准。

其他代码请看\ganymed-ssh2-build210\examples\下的例子吧。

本文为原创,欢迎转载,转载请注明出处BlogJava。[该工具Jar包可在:http://download.csdn.net/detail/shenjianox/7769783及文档下载地址ganymed-ssh2简介:Ganymed SSH-2 for Java是用纯Java实现SSH-2协议的一个包。在使

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值