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

本文介绍使用Java通过SSH远程连接并执行Linux Shell脚本的方法。利用ganymed-ssh2-build210.jar库,演示了如何编写Java程序来连接远程服务器、执行指定的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:

public class RmtShellExecutor {


private Connection conn;

private String ip;

private String usr;

private String psword;
private String charset = Charset.defaultCharset().toString();

private static final int TIME_OUT = 1000 * 5 * 60;


public RmtShellExecutor(ShellParam param) {
this.ip = param.getIp();
this.usr = param.getUsername();
this.psword = param.getPassword();
}


public RmtShellExecutor(String ip, String usr, String ps) {
this.ip = ip;
this.usr = usr;
this.psword = ps;
}


private boolean login() throws IOException {
conn = new Connection(ip);
conn.connect();
return conn.authenticateWithPassword(usr, psword);
}


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;
}


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;


public abstract interface ChannelCondition
{

public static final int TIMEOUT = 1;


public static final int CLOSED = 2;


public static final int STDOUT_DATA = 4;


public static final int STDERR_DATA = 8;


public static final int EOF = 16;


public static final int EXIT_STATUS = 32;


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。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值