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脚本。 - import java.io.BufferedReader;
- 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. ...
随机推荐
- js判断是否安装flash player及当前版本 和 检查flash版本是否需要升级
一.js检查flash版本升级 for (var i = 0, len = navigator.plugins.length; i < len; i++) { var plugin = navi ...
- Nginx作为负载均衡器upstream
Nginx中与proxy模块结合使用的模块中,最常用的当属upstream模块.upstream模块可定义一个新的上下文,它包含了一组upstream服务器,这些服务器可能被赋予了不同的权重.不同的类 ...
- 利用 fdisk进行分区
):fdisk命令参数 p:打印分区表. n:新建一个新分区. d:删除一个新分区. q:退出不保存. w:退出且保存. 例子: 先看下磁盘: root@archiso ~ # lsblk 在这里对磁 ...
- 基于jquery hover图片遮罩层滑动
分享一款基于jquery hover图片遮罩层滑动.这是一款仿腾讯课堂的鼠标悬停经过图片遮罩透明层滑动效果.效果图如下: 在线预览 源码下载 实现的代码. html代码: <div clas ...
- 基于jQuery实现滚动新闻代码下载
分享一款基于jQuery实现滚动新闻代码下载.这是一款基于bootstrup 3实现的响应式jQuery滚动新闻插件.效果图如下: 在线预览 源码下载 实现的代码. html代码: <div ...
- tomcat 远程命令执行漏洞复现
影响范围 Apache Tomcat 7.0.0 - 7.0.81 不受影响的版本 Apache Tomcat 8.x Apache Tomcat 9.x 漏洞分析 在Tomcat安装目录下的配置文件 ...
- [转]JAVA泛型通配符T,E,K,V区别,T以及Class<T>,Class<?>的区别
原文地址:https://www.jianshu.com/p/95f349258afb 1. 先解释下泛型概念 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被 ...
- Mac OS X上搭建Apache、PHP、MySQL的Web服务器
mac OS 系统太帅了,安装php的环境如此简单,大赞一个! 转载自http://jingyan.baidu.com/article/39810a23e1939fb636fda6a9.html 在M ...
- html绝对路径与相对路径
文件,图片和html文档同一个目录的直接写文件名即可(相对路径). 工作中一般使用相对路径,项目放到服务器上部署不能保证绝对路径不出错.
- Linux0.11从开机到准备执行main函数的启动学习
最近一直在看操作系统以及内核设计的东西,不确定自己有能力会参与到类似的开发之中,但是争取能自己改造这内核玩一下,然后按照Linux From Scratch那样的把改造后的系统编译运行就心满意足了.正 ...