Java实践 — SSH远程执行Shell脚本
1. SSH简介
2. 实现原理
3. 示例代码及分析
- SSHCommandExecutor.java:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Vector; import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session; /**
* This class provide interface to execute command on remote Linux.
*/ public class SSHCommandExecutor {
private String ipAddress; private String username; private String password; public static final int DEFAULT_SSH_PORT = 22; private Vector<String> stdout; public SSHCommandExecutor(final String ipAddress, final String username, final String password) {
this.ipAddress = ipAddress;
this.username = username;
this.password = password;
stdout = new Vector<String>();
} public int execute(final String command) {
int returnCode = 0;
JSch jsch = new JSch();
MyUserInfo userInfo = new MyUserInfo(); try {
// Create and connect session.
Session session = jsch.getSession(username, ipAddress, DEFAULT_SSH_PORT);
session.setPassword(password);
session.setUserInfo(userInfo);
session.connect(); // Create and connect channel.
Channel channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(command); channel.setInputStream(null);
BufferedReader input = new BufferedReader(new InputStreamReader(channel
.getInputStream())); channel.connect();
System.out.println("The remote command is: " + command); // Get the output of remote command.
String line;
while ((line = input.readLine()) != null) {
stdout.add(line);
}
input.close(); // Get the return code only after the channel is closed.
if (channel.isClosed()) {
returnCode = channel.getExitStatus();
} // Disconnect the channel and session.
channel.disconnect();
session.disconnect();
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return returnCode;
} public Vector<String> getStandardOutput() {
return stdout;
} public static void main(final String [] args) {
SSHCommandExecutor sshExecutor = new SSHCommandExecutor("xx.xx.xx.xx", "username", "password");
sshExecutor.execute("uname -s -r -v"); Vector<String> stdout = sshExecutor.getStandardOutput();
for (String str : stdout) {
System.out.println(str);
}
}
}getSession()只是创建一个session,需要设置必要的认证信息之后,调用connect()才能建立连接。
调用openChannel(String type) 可以在session上打开指定类型的channel。该channel只是被初始化,使用前需要先调用connect()进行连接。Channel的类型可以为如下类型:- shell - ChannelShell
- exec - ChannelExec
- direct-tcpip - ChannelDirectTCPIP
- sftp - ChannelSftp
- subsystem - ChannelSubsystem
其中,ChannelShell和ChannelExec比较类似,都可以作为执行Shell脚本的Channel类型。它们有一个比较重要的区别:ChannelShell可以看作是执行一个交互式的Shell,而ChannelExec是执行一个Shell脚本。 - MyUserInfo:
import com.jcraft.jsch.UserInfo; /**
* This class provide interface to feedback information to the user.
*/
public class MyUserInfo implements UserInfo {
private String password; private String passphrase; @Override
public String getPassphrase() {
System.out.println("MyUserInfo.getPassphrase()");
return null;
} @Override
public String getPassword() {
System.out.println("MyUserInfo.getPassword()");
return null;
} @Override
public boolean promptPassphrase(final String arg0) {
System.out.println("MyUserInfo.promptPassphrase()");
System.out.println(arg0);
return false;
} @Override
public boolean promptPassword(final String arg0) {
System.out.println("MyUserInfo.promptPassword()");
System.out.println(arg0);
return false;
} @Override
public boolean promptYesNo(final String arg0) {
System.out.println("MyUserInfo.promptYesNo()");
System.out.println(arg0);
if (arg0.contains("The authenticity of host")) {
return true;
}
return false;
} @Override
public void showMessage(final String arg0) {
System.out.println("MyUserInfo.showMessage()");
}
}MyUserInfo实现了接口UserInfo,主要是为获得运行执行的用户信息提供接口。大部分实现方法中,没有做实质性的工作,只是输出一下trace信息,帮助判断哪个方法被执行过。4. 执行结果分析
1. 如果不设置UserInfo,会抛出JSchException异常,提示找不到host:
2. 如果MyUserInfo实现了接口UserInfo,但是只是@Override一些函数,会出现如下错误:
虽然可以找到host,但是会拒绝访问host。发现所有@Override函数中,get方法返回的都是null,prompt方法返回的都是false。3. 为了判断这些Override的methods中,那些是有用的,在每个method中加入trace信息。发现只有promptYesNo(final String)会被调用到,输出如下图所示:
4. promptYesNo(final String)是向用户提出一个yes或者no的问题,来决定是否允许连接远程主机。这才是决定连接是否成功的一个关键函数。如果返回值为true,则允许连接;如果返回值为false,则拒绝连接。最后正确连接后的输出入下图所示:
Reference
来自:http://blog.csdn.net/jmyue/article/details/14003783
Java实践 — SSH远程执行Shell脚本的更多相关文章
- Java实践 — SSH远程执行Shell脚本(转)
原文地址:http://www.open-open.com/lib/view/open1384351384024.html 1. SSH简介 SSH是Secure Shell的缩写,一 ...
- Java SSH远程执行Shell脚本实现(转)
前言 此程序需要ganymed-ssh2-build210.jar包(下载地址:http://www.ganymed.ethz.ch/ssh2/) 为了调试方便,可以将\ganymed-ssh2-bu ...
- JAVA远程执行Shell脚本类
1.java远程执行shell脚本类 package com.test.common.utility; import java.io.IOException; import java.io.Input ...
- [linux] ssh远程执行本地脚本
1.ssh密钥登录 略 2.免确认机器指纹,ssh -o StrictHostKeyChecking=no [root@XM-v125 ~]# ssh wykai@192.168.0.110 The ...
- Python ssh 远程执行shell命令
工具 python paramiko 远程执行命令 import paramiko ssh = paramiko.SSHClient() key = paramiko.AutoAddPolicy() ...
- Java SSH远程执行Shell命令、shell脚本实现(Ganymed SSH)
jar包下载地址: http://www.ganymed.ethz.ch/ssh2/ 此源码的好处就是没有依赖很多其他的包,拷贝过来干干净净.具体代码实现可以看下文,或参考官方文档,在下载的压缩包里g ...
- 远程执行shell脚本的小技巧
很多时候需要批量跑脚本执行任务,但又不想分发再执行,而是直接一条命令下去就跑脚本,该怎么玩比较嗨? 例如以下脚本: #!/bin/bash echo "$@" echo " ...
- 远程执行shell脚本
ssh -p2016 apache@10.10.18.130 '/bin/sh /data/www/vhosts/WOStest3_ENV/update_env.sh' 需要设置shell远程免密码登 ...
- SaltStack远程执行shell脚本
编辑文件fansik.sh 脚本内容: #!/bin/bash # Author: fansik # data: 2017年 09月 26日 星期二 :: CST touch /tmp/fansik. ...
随机推荐
- NGUI制作字体的三种方法
主要参考两篇博文: (1).NGUI制作字体的三种方法 (2).使用位图字体工具BMFont从图片生成自定义字体 1.BMFont下载地址 http://www.angelcode.com/produ ...
- 【内核】linux2.6版本内核编译配置选项(一)
Linux 2.6.19.x 内核编译配置选项简介 作者:金步国 版权声明 本文作者是一位自由软件爱好者,所以本文虽然不是软件,但是本着 GPL 的精神发布.任何人都可以自由使用.转载.复制和再分发, ...
- 什么是lib文件,lib和dll的关系如何
(1)lib是编译时需要的,dll是运行时需要的. 如果要完成源代码的编译,有lib就够了. 如果也使动态连接的程序运行起来,有dll就够了. 在开发和调试阶段,当然最好都有. (2)一般的动态库程序 ...
- 生产者消费者问题Java三种实现
生产者-消费者Java实现 2017-07-27 1 概述 生产者消费者问题是多线程的一个经典问题,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品. 解决生产者/ ...
- Python socket编程客户端与服务端通信
[本文出自天外归云的博客园] 目标:实现客户端与服务端的socket通信,消息传输. 客户端 客户端代码: from socket import socket,AF_INET,SOCK_STREAM ...
- Oracle Database 11g Release 2 Standard Edition and Enterprise Edition Software Downloads
Oracle Database 11g Release 2 Standard Edition and Enterprise Edition Software DownloadsOracle 数据库 1 ...
- WebApi增删改查Demo
1.新建webapi项目 2.配置WebApiConfig public const string DEFAULT_ROUTE_NAME = "MyDefaultRoute"; p ...
- [转]bootstrap的table插件动态加载表头
原文地址:https://blog.csdn.net/abubu123/article/details/78060321 bootstrap的table属性已经很熟悉了,最近遇到一个问题,犹豫每个列表 ...
- [Python Essential Reference, Fourth Edition (2009)]读书笔记
Python programs are executed by an interpreter. When you use Python interactively, the special varia ...
- [root]既然sudo 可以暂时获取root权限,那么为何还需要root这个用户呢
既然sudo 可以暂时获取root权限,那么为何还需要root这个用户呢 sudo 非root用户可以临时行使root权限,也就是非root用户可以操作该系统下的任何文件,仍然存在安全风险,怎么解释? ...