java 利用ganymed-ssh2 远程执行linux shell 命令

2023-11-18

早期的ganymed-ssh2包也可以实现远程调研linux shell 命令,但是这个包最新版本是2014年之后,就没有更新了,发现linux 操作系统安装 open-ssh 8.5及更高级版本,就一直提示连接失败.(可以使用jsch 最新版本更新到2018年,网上demo 很多 ,目前测试可以使用,后续可能出现ganymed-ssh2 相同问题协议不支持,无法连接情况,sshd-core 是apache-mina 的项目一直在更新,推荐使用)

package ganymed_ssh2;

import ch.ethz.ssh2.ChannelCondition;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;

import java.io.InputStream;
import java.io.PrintWriter;
import java.nio.charset.Charset;

public class Ssh2Util {
    private Connection conn;
    private String charset = Charset.defaultCharset().toString();

    /**
     * 连接到指定的IP
     *
     * @param user
     * @param passwd
     * @param ip
     * @param port
     * @return
     * @throws Exception
     */
    public boolean connect(String user, String passwd, String ip, int port) throws Exception {
        this.conn = new Connection(ip, port);
        this.conn.connect();
        return this.conn.authenticateWithPassword(user, passwd);
    }

    /**
     * 执行相关的命令
     * 非交互式
     *
     * @param command
     * @param user
     * @param passwd
     * @param ip
     * @param port
     * @return
     * @throws Exception
     */
    public String execCmd(String command, String user, String passwd, String ip, int port) throws Exception {
        InputStream stdOut = null;
        InputStream stdErr = null;
        StringBuilder buf = new StringBuilder();
        try {
            System.out.println("连接地址:" + ip + ":" + port);
            buf.append("\n连接地址:" + ip + ":" + port + "\n");
            if (connect(user, passwd, ip, port)) {
                Session session = this.conn.openSession();
                System.out.println("执行命令:" + command);
                buf.append("执行命令:" + command + "\n");
                session.execCommand(command);
                stdOut = new StreamGobbler(session.getStdout());
                String outStr = processStream(stdOut, this.charset);
                stdErr = new StreamGobbler(session.getStderr());
                String outErr = processStream(stdErr, this.charset);
                System.out.println("执行结果:" + outStr + outErr);
                buf.append("执行结果:" + outStr + outErr + "\n");
                int ret = session.getExitStatus();
                System.out.println("返回代码:" + ret);
                buf.append("返回代码:" + ret);
            } else {
                System.out.println("登录远程机器失败,请检查网络连接及用户密码是否正确!!!");
                buf.append("登录远程机器失败,请检查网络连接及用户密码是否正确!!!");
            }

        } catch (Exception e) {
            e.printStackTrace();
            buf.append("执行脚本时出现异常,命令:" + command + "-" + e.getMessage());
        } finally {
            if (null != conn) {
                conn.close();
            }
            if (null != stdOut) {
                stdOut.close();
            }
            if (null != stdErr) {
                stdErr.close();
            }
        }
        return buf.toString();
    }


    /**
     * 交互式命令
     *
     * @param commands
     * @param user
     * @param passwd
     * @param ip
     * @param port
     * @throws Exception
     */
    public void execCmdOnPTY(String[] commands, String user, String passwd, String ip, int port)
            throws Exception {
        InputStream stdOut = null;
        InputStream stdErr = null;
        Session session = null;
        try {
            if (connect(user, passwd, ip, port)) {
                session = this.conn.openSession();
                session.requestPTY("bash");
                session.startShell();
                try (PrintWriter out = new PrintWriter(session.getStdin());) {
                    for (String command : commands) {
                        System.out.println("执行命令:" + command);
                        out.println(command);
                    }
                    out.println("exit");
                    stdOut = new StreamGobbler(session.getStdout());
                    String outStr = processStream(stdOut, this.charset);
                    stdErr = new StreamGobbler(session.getStderr());
                    String outErr = processStream(stdErr, this.charset);
                    System.out.println("执行结果(out):" + outStr);
                    System.out.println("执行结果(err):" + outErr);
                    int waitForCondition = session.waitForCondition(
                            ChannelCondition.CLOSED | ChannelCondition.EOF | ChannelCondition.EXIT_STATUS, 0);
                    System.out.println("waitForCondition:" + waitForCondition);
                    int ret = session.getExitStatus();
                    System.out.println("返回代码:" + ret);
                    if (ret != 0) {
                        throw new Exception("导出命令不能正常执行结束!!!");
                    }
                    if (null != stdOut) {
                        stdOut.close();
                    }
                    if (null != stdErr) {
                        stdErr.close();
                    }
                } catch (Throwable t) {
                    t.printStackTrace();
                }
            } else {
                System.out.println("登录远程机器失败,请检查网络连接及用户密码是否正确!!!");
                throw new Exception("登录远程机器失败,请检查网络连接及用户密码是否正确!!!");
            }
        } catch (Exception e) {
            throw e;
        } finally {
            if (null != session) {
                session.close();
            }
            if (null != conn) {
                conn.close();
            }
            if (null != stdOut) {
                stdOut.close();
            }
            if (null != stdErr) {
                stdErr.close();
            }
        }
    }


    /**
     * 输出日志
     */
    private String processStream(InputStream in, String charset) throws Exception {
        StringBuilder strBuf = new StringBuilder();
        byte[] buf = new byte[1024];
        int num = 0;
        while ((num = in.read(buf)) != -1) {
            strBuf.append(new String(buf, 0, num, charset).trim());
            buf = new byte[1024];
        }
        return strBuf.toString();
    }

}

		<!-- https://mvnrepository.com/artifact/ch.ethz.ganymed/ganymed-ssh2 -->
		<dependency>
			<groupId>ch.ethz.ganymed</groupId>
			<artifactId>ganymed-ssh2</artifactId>
			<version>262</version>
		</dependency>

如果感觉对您有帮助,点个赞支持一下

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java 利用ganymed-ssh2 远程执行linux shell 命令 的相关文章

随机推荐

  • Ubuntu16.04 获取Root 权限

    如果是第一次获得Root权限那么首先要设置root密码 sudo passwd root 获取root权限 su root 输入之前你设置的密码 退出root exit
  • Quartz教程--快速入门

    欢迎来到quartz快速入门教程 阅读本教程 你将会了解 quartz下载 quartz安装 根据你的需要 配置Quartz 开始一个示例应用 当熟悉了quratz调度的基本功能后 可以尝试一些更高级的特性 比如Where 这个一个企业级功
  • 深聊测试开发之:从订单支付流程来聊一聊,如何预防重复支付,建议收藏。

    如何预防订单重复支付 1 引言 2 订单支付流程 2 1 支付流程 2 2 订单状态 3 订单重复支付原因 3 1 掉单 3 2 未防重 3 3 多渠道 4 防止重复支付 4 1 加锁 4 2 缓存结果 4 3 支付中取消流水 4 4 已支
  • 微信小程序canvas画布绘制;canvas画布图片保存

    微信小程序canvas画布绘制 wx createSelectorQuery select canvas fields node true size true exec res gt let ctx res 0 node getContex
  • 关于域名暂时解析失败的问题 (Temporary failure in name resolution)

    相信很多小伙伴在运行爬虫程序的时候 都会遇到这么个错误 Temporary failure in name resolution 什么意思呢 昨天还运行的好好的呢 域名暂时解析失败 但是呢 在浏览器输入网址 还是可以打开这个网站的 看网站内
  • Win10开启高性能、卓越性能模式的方法

    Win10开启高性能 卓越性能模式的方法 一 老办法 1 打开PowerShell 管理员模式 Win X 选择 2 输入以下命令 powercfg duplicatescheme e9a42b02 d5df 448d aa00 03f14
  • MFC 动态链接库(DLL)中创建窗口失败

    毕业设计写一个关于网络的项目 在客户端把WSAAsyncSelect网络模型封装在了动态链接库中 点击运行 在UI线程中发现 创建一个CFrameWnd窗口的时候程序报错了 均显示ASSERT afxCurrentResourceHandl
  • LeetCode-450.删除二叉搜索树中的节点

    给定一个二叉搜索树的根节点 root 和一个值 key 删除二叉搜索树中的 key 对应的节点 并保证二叉搜索树的性质不变 返回二叉搜索树 有可能被更新 的根节点的引用 一般来说 删除节点可分为两个步骤 首先找到需要删除的节点 如果找到了
  • How far away ? 【HDU - 2586】【DFS+链式前向星优化】

    题目链接 其实这道题可以不用链式前向星优化换做vector lt gt 也是可以跑的 只是会许会慢些而已 来换个中文题意好读些 勇气小镇是一个有着n个房屋的小镇 为什么把它叫做勇气小镇呢 这个故事就要从勇气小镇成立的那天说起了 修建小镇的时
  • URL 编码与解码使用详解

    1 介绍 1 1 背景 网页的 URL 只能包含合法的字符 合法字符分成两类 URL 元字符 分号 逗号 斜杠 问号 冒号 at 等号 加号 美元符号 井号 语义字符 a z A Z 0 9 连词号 下划线 点 感叹号 波浪线 星号 单引号
  • mysql两个字段进进行排序

    排序 我想先将记录先按照last time由大到小排序 在last time值相同的条件下按照id值由大到小排列 以保证晚发布的信息有优先的露面的机会 请问这个sql语句应该如何写 order by last time desc id de
  • 三步在两台服务器间迁移conda环境

    引言 背景是我现在要跑的实验在一台服务器上跑有点来不及了 需要将conda环境和文件一起迁移到另一台服务器上 文件的迁移可以用scp或者rsync 但是conda虚拟环境的迁移则不行 步骤 step 1 将当前的虚拟幻境信息写入enviro
  • 制造业基本ERP管理系统模块全解析

    一 销售模块 1 成品分类 客户分类需要能做到多维统计 比如一个产品既属于成品又属于机架 还可以属于铝制品 成品和客户都必须能实现这种多维分类 相应报表也能根据这些多维分类进行分析统计 2 查看该销售订单时 可以直接查看到该张销售订单的执行
  • 最好不要过度处理EEG数据

    自动预处理方法对于处理大量公开可用的EEG 脑电图 数据库至关重要 但由于我们缺乏用于比较这些方法的数据质量指标 因此最佳方法仍然未知 在这里 我们设计了一个简单但稳健的EEG数据质量度量标准 用于评估两个实验条件之间在100毫秒刺激后时间
  • 报错为method does not override method from its superclass解决

    你要重写接口的方法就得让实现类实现接口 public class UserServiceImpl implements UserService 没有实现接口就加重写注解 Override 系统不知道重写了什么接口方法 肯定报错 建议巩固一下
  • 为什么函数y=f(x)的导数dy/dx可以适用分数运算呢?

    一 问题背景 在同济大学高等数学关于导数的内容中 如果函数y f x 可以由参数方程 表示 且三个函数皆可导 且x的值不为0 则 才开始看这个公式推导时 觉得没什么问题 仔细一想 dy dx是导数的表示符号 为什么这个符号可以适用分数运算公
  • Hive 视图和索引

    一 视图 1 1 简介 Hive 中的视图和 RDBMS 中视图的概念一致 都是一组数据的逻辑表示 本质上就是一条 SELECT 语句的结果集 视图是纯粹的逻辑对象 没有关联的存储 Hive 3 0 0 引入的物化视图除外 当查询引用视图时
  • Spring的Factories机制介绍

    项目场景 Spring的Factories机制介绍 Spring的Factories机制介绍
  • 如何使用vscode开发uniapp并运行

    如何使用vscode开发uniapp并运行 1 必须先下载HBuilderX然后导入你需要开发的uni项目 2 然后在vscode中再次打开你的uni项目 3 去vscode插件市场安装一个uni helper这个插件 4 即可在vscod
  • java 利用ganymed-ssh2 远程执行linux shell 命令

    早期的ganymed ssh2包也可以实现远程调研linux shell 命令 但是这个包最新版本是2014年之后 就没有更新了 发现linux 操作系统安装 open ssh 8 5及更高级版本 就一直提示连接失败 可以使用jsch 最新