前言

此程序需要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 $ $ $#
#print $

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 = * * ; /** *//**
* 构造函数
* @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 = -;
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[];
StringBuilder sb = new StringBuilder();
while (in.read(buf) != -) {
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
outErr=
// 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 = ; /** *//**
* 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 = ; /** *//**
* There is stdout data available that is ready to be consumed.
*/
public static final int STDOUT_DATA = ; /** *//**
* There is stderr data available that is ready to be consumed.
*/
public static final int STDERR_DATA = ; /** *//**
* 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 = ; /** *//**
* 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 = ; /** *//**
* The exit signal of the remote process is available.
*/
public static final int EXIT_SIGNAL = ; }

当我们把myTest.sh修改为如下内容:
echo $1 $2 $#
print $1由于我使用的linux机器上没有print命令,所以print $1会报错:command not found。

接下来再让我们执行一下,看看控制台的结果:

outStr=java Know
outErr=/sshapp/myshell/myTest.sh: line : print: command not found 此时shell脚本出现错误,getExitStatus方法返回127.

在实际应用中,可以将outStr和outErr记录到日志中,以便维护人员查看shell的执行情况,
而getExitStatus的返回值,可以认为是此次执行是否OK的标准。

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

转自:http://rainyear.iteye.com/blog/1339825

Java SSH远程执行Shell脚本实现(转)的更多相关文章

  1. Java实践 — SSH远程执行Shell脚本(转)

    原文地址:http://www.open-open.com/lib/view/open1384351384024.html 1. SSH简介         SSH是Secure Shell的缩写,一 ...

  2. Java实践 — SSH远程执行Shell脚本

    1. SSH简介         SSH是Secure Shell的缩写,一种建立在应用层和传输层基础上的安全协议.SSH在连接和传送过程中会加密所有数据,可以用来在不同系统或者服务器之间进行安全连接 ...

  3. Java SSH远程执行Shell命令、shell脚本实现(Ganymed SSH)

    jar包下载地址: http://www.ganymed.ethz.ch/ssh2/ 此源码的好处就是没有依赖很多其他的包,拷贝过来干干净净.具体代码实现可以看下文,或参考官方文档,在下载的压缩包里g ...

  4. JAVA远程执行Shell脚本类

    1.java远程执行shell脚本类 package com.test.common.utility; import java.io.IOException; import java.io.Input ...

  5. Java实践-远程调用Shell脚本并获取输出信息

    1.添加依赖 <dependency> <groupId>ch.ethz.ganymed</groupId> <artifactId>ganymed-s ...

  6. [linux] ssh远程执行本地脚本

    1.ssh密钥登录 略 2.免确认机器指纹,ssh -o StrictHostKeyChecking=no [root@XM-v125 ~]# ssh wykai@192.168.0.110 The ...

  7. Python ssh 远程执行shell命令

    工具 python paramiko 远程执行命令 import paramiko ssh = paramiko.SSHClient() key = paramiko.AutoAddPolicy() ...

  8. Shell 脚本 —— java 代码远程调用shell脚本重启 tomcat

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 1.创建maven 工程 ​ maven 依赖: <dependency> <grou ...

  9. 远程执行shell脚本的小技巧

    很多时候需要批量跑脚本执行任务,但又不想分发再执行,而是直接一条命令下去就跑脚本,该怎么玩比较嗨? 例如以下脚本: #!/bin/bash echo "$@" echo " ...

随机推荐

  1. Shapefile文件中的坐标绘制到屏幕时的映射模式设置

    pDC->SetMapMode(MM_ANISOTROPIC ); //首先选择MM_ANISOTROPIC映射模式,其它映射模式都不合适 pDC->SetWindowExt( max(a ...

  2. 初学JavaScript(入门一)

    javaScript是世界上最流行的脚本语言   在我们的手机.电脑设备上所浏览的所有网页,以及基于HTML5手机App的交互都是通过javaScript驱动的,所以javascript是前端工作的一 ...

  3. Chapter11:关联容器

    当用decltype来获得一个函数指针类型时,必须加上一个*来指出我们要使用一个给定函数类型的指针.decltype<CompareIsbn>*. map<string, int&g ...

  4. c语言的几个重要知识点

      内存结构 这是核心中的核心,请仔细看完,充分理解,否则请不要看下一节内容. 每个程序一启动都有一个大小为4GB的内存,这个内存叫虚拟内存,是概念上的,真正能用到的,只是很小一部分,一般也就是在几百 ...

  5. Python的数据处理学习(三)

    三.类的继承   Python 的class可以允许从零开始创建一个定制类,就像文章(二)创建Athlete类一样,也可以通过继承现有的其他类类创建一个类,这也包括用List.set和dict提供的p ...

  6. 【转】SQL常用的语句和函数

    原文链接:http://www.cnblogs.com/mailingfeng/archive/2013/01/07/2850116.html order by 的数值型灵活使用 select * f ...

  7. vim之pydiction插件

    [vim之pydiction插件] It consists of three main files: python_pydiction.vim -- Vim plugin. complete-dict ...

  8. Leetcode226:Invert Binary Tree

    Invert a binary tree. 4 / \ 2 7 / \ / \ 1 3 6 9 to 4 / \ 7 2 / \ / \ 9 6 3 1 /** * Definition for a ...

  9. windows服务安装及卸载

    1)安装脚本Install.bat%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe JobSchedule.exeNet ...

  10. hdu-4753-Fishhead’s Little Game-记忆化搜索

    网赛的一道题目,当时没做出来. 由题意可知,最多只有12条边未知. 所以最多只有(1<<12)种状态. 所以记忆化搜索这种状态下,枚举添加任意一条边之后的状态的最优值. #include& ...