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方法,通过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的标准。
其他代码请看\ganymed-ssh2-build210\examples\下的例子吧。
本文为原创,欢迎转载,转载请注明出处BlogJava。
分享到:
相关推荐
在本篇博客中,我们将探讨如何使用Java通过SSH远程执行Shell脚本,这对于系统管理和自动化任务非常有用。我们将重点关注`ExecuteRemoteShell.java`这个文件,它应该包含了实现这一功能的核心代码。 首先,为了实现...
Java 远程调用Shell脚本客户端包是一个实用的工具,专为开发者设计,使得在Java应用程序中执行远程Shell命令变得简单而高效。这个包的主要功能是通过Java代码发起对远程服务器上的Shell脚本的调用,从而实现跨平台的...
接下来,我们要介绍如何通过Java使用JSch库实现SSH远程连接Linux服务器。JSch是一个纯Java实现的SSH2库,可以用于执行shell命令、文件传输等操作。 首先,确保你的项目中已经添加了JSch的依赖。然后,你可以使用...
这个“远程shell调用.rar”文件包含了一个基于Java的工具,它允许开发者通过SSH连接到Linux服务器并执行Shell脚本,从而简化了这一过程。 首先,让我们了解一下SSH2。SSH2是SSH协议的第二版,相比SSH1,它提供了更...
该工具是基于SSH2协议的实现,在使用它的过程中非常容易,只需要指定合法的用户名口令,或者授权认证文件,就可以创建到远程Linux主机的连接,在建立起来的会话中调用该Linux主机上的脚本文件,执行相关操作。
综上所述,Java调用远程Shell脚本涉及的主要知识点包括:SSH协议,Ganymed SSH-2库的使用,建立SSH连接,执行远程命令,处理输出,以及参数的动态配置。在实际应用中,这些技术可以帮助开发者实现远程服务器的自动化...
这个"shell脚本远程启动其他服务器的tomcat传输文件自动登录判断启动停止"的方案,就是一种典型的自动化运维实践,它结合了多个核心工具和技术,包括shell脚本、expect、ssh以及scp,用于实现远程服务器管理与文件...
Java远程调用Shell脚本并获取输出信息 本文主要介绍了Java远程调用Shell脚本...本文介绍了Java远程调用Shell脚本并获取输出信息的方法,使用了Java的SSH客户端来连接远程Linux服务器,执行Shell脚本,并获取输出信息。
Python – paramiko 模块远程执行ssh 命令 nohup 不生效的问题解决 1、使用 paramiko 模块ssh 登陆到 linux 执行nohup命令不生效 # 执行命令 def command(ssh_config, cmd, result_print=None, nohup=False): ssh ...
Java 实现模拟 SSH 和 Telnet 登陆,以及发送与接收命令是网络编程中常见的需求,主要应用于自动化测试、远程系统管理或数据交换等场景。在本文中,我们将深入探讨如何利用 Java 实现这一功能。 首先,SSH(Secure ...
接下来,在Java程序中,你可以使用以下代码来执行远程shell脚本: ```java import com.jcraft.jsch.*; public class RunRemoteScript { private static final String REMOTE_HOST = "1.1.1.1"; private static ...
Jsch是Java Secure Channel的一个开源实现,它可以提供SSH2协议下的文件传输、端口转发、远程命令执行等功能。JSchAPI是Jsch库提供的接口,开发者可以通过它与远程主机建立安全连接,并执行Shell命令。 1. **安装...
总之,通过Java操作Linux服务器并执行shell脚本,可以实现自动化运维、远程数据获取等多种功能。结合Apache Commons库,我们可以编写出高效、可靠的远程管理工具。在实际开发中,一定要注意安全性,例如使用密钥对...
Java SSH 执行命令主要涉及到Java编程语言与SSH(Secure Shell)协议的交互,通常用于远程服务器的管理和自动化任务执行。SSH是一种网络协议,允许用户安全地在不安全的网络上进行远程登录和其他网络服务。在Java中...
总之,Java结合ganymed-ssh2-build210.jar库可以实现强大的SSH远程连接功能,使开发者能够在Java应用中安全、便捷地与Linux服务器交互,执行各种远程操作。无论是简单的命令执行还是复杂的自动化脚本,这个库都能...
总的来说,这些资源为你提供了在Java环境中调用Shell脚本所需要的基础工具和示例,涵盖了SSH连接、命令执行和交互式脚本控制。通过学习和使用这些库,你将能够构建强大的系统管理工具和自动化解决方案。
在java里可以通过Ganymed SSH-2, Expect4j等实现ssh登录,由于Ganymed SSH-2是纯java实现,并且可以实现scp,sftp等,因此我们采用Ganymed SSH-2 1> 下载安装 从http://code.google.com/p/ganymed-ssh-2/ 下载...
sshxcute 就是这样一个框架工具集,它基于 JSCH 构建,允许工程师利用Java 代码通过 SSH 连接远程批量执行 Linux/UNIX 系统上的命令或者脚本,同时加入了判断成功与否,取回输出等多种实用功能。sshxcute 不管是针对...
在IT行业中,Java是一种广泛应用的编程语言,而Shell脚本则是Linux或Unix系统中的命令行脚本,用于自动化执行一系列任务。将Java与Shell脚本结合使用,可以在Java应用程序中执行系统级操作或者调用复杂的命令行流程...