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. ...
随机推荐
- Python写入连接mysql失败
执行如下连接数据库的语句: engine = create_engine('mysql://root:root@127.0.0.1/stock?charset=utf8') 报错如下: ImportE ...
- 好用的vim插件
# 好用的vim插件 ### 简介------------------------------ 记录vim好用的插件 ### vimcdoc vim中文帮助文档-------------------- ...
- MySQL 中联合查询效率分析
目前我有两个表,一个keywords和一个news表.keyword存放关键词是从news中提取,通newsid进行关联,两表关系如图: keywords中存有20万条数据,news中有2万条数据,现 ...
- div模态显示内容
业务需要,上传的图片,本地显示大图: 模态代码: <div onclick="hidebigimg()" class = "bg-model" style ...
- 安卓Activity生命周期(转)
http://www.oschina.net/question/54100_27841 启动:onCreate()->onStart()->onResume 当从Activity界面直接按 ...
- C语言 · LOG大侠
标题:LOG大侠 atm参加了速算训练班,经过刻苦修炼,对以2为底的对数算得飞快,人称Log大侠. 一天,Log大侠的好友 drd 有一些整数序列需要变换,Log大侠正好施展法力... 变换的规则是: ...
- TP v5中环境变量在项目中的应用
环境变量,顾名思义就是在不同的系统环境,同一个变量的值可以有所不同. 如开发环境.测试环境与正式环境下,数据库配置.静态资源文件Url前缀.缓存.各种key等配置都不相同,对于提交到仓库中的代码,理论 ...
- linux 重定向 标准错误与标准输出到同一文件
Linux Shell 环境中的输入输出重定向,用符号<和>来表示.0.1和2分别表示标准输入.标准输出和标准错误. 1.重定向标准输出到文件: cat foo > foo.txt ...
- js 窗口抖动
<title>窗口抖动</title> <style> body{margin:50px; } #qq{position:relative;} span{paddi ...
- 全国地区的省份、城市、区县 最新Sql脚本
IF (EXISTS(SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[TB_Province]') AND type =' ...