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. ...
随机推荐
- 【电子基础】IIC总线工作原理
IIC总线工作原理 I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化. 起始和终止信号 :SCL线为 ...
- Vue右键菜单
rightShow(item) { this.isPersoncontextMenus = true; let menu = document.getElementById("msgRigh ...
- Python3.5爬取cbooo.cn数据并且同步到mysql中
#!/usr/local/bin/python # -*- coding: utf-8 -*- # Python: 3.5 # Author: wucl(),zhenghai.zhang # Prog ...
- java 多线程 19: ReentrantLock 与 Condition
ReentrantLock ReentrantLock,一个可重入的互斥锁,它具有与使用synchronized方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大. Reentran ...
- python-标识符(Identifiers)和关键字(keywords)
标识符:Identifiers 标识符必须以字母(大小写均可)或者"_"开头,接下来可以重复0到多次(字母|数字|"_") 特点: 1.没有长度限制 2.区分大 ...
- [转]获取JAVA[WEB]项目相关路径的几种方法
http://blog.csdn.net/yaerfeng/article/details/7297479/ 在jsp和class文件中调用的相对路径不同. 在jsp里,根目录是WebRoot 在cl ...
- setOnPageChangeListener 过时了怎么办?
今天使用ViewPager发现setOnPageChangeListener的方法竟然过期了.并且AS编译不通过了,最后查了一下原来把set换成add了,代码例如以下: setOnPageChange ...
- 'Project Name' was compiled with optimization
'Project Name' was compiled with optimizationhtml, body {overflow-x: initial !important;}html { font ...
- JVM内存的设置
一.JVM内存的设置的原理 默认的java虚拟机的大小比较小,在对大数据进行处理时java就会报错:java.lang.OutOfMemoryError. 设置jvm内存的方法,对于单独的.class ...
- linux进程cpu资源分配命令nice,renice,taskset
进程cpu资源分配就是指进程的优先权(priority).优先权高的进程有优先执行权利.配置进程优先权对多任务环境的linux很有用,可以改善系统性能.还可以把进程运行到指定的CPU上,这样一来,把不 ...