利用ganymed-ssh2远程执行其它Linux机器上的shell命令
时间:2022-04-23
本文章向大家介绍利用ganymed-ssh2远程执行其它Linux机器上的shell命令,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
实际应用中,有时候需要从web管理界面上,远程去启动其它linux主机上的程序,利用ssh协议可以方便的满足这一需求。事实上hadoop架构中,从nn上启动dn时,就是利用了免密码ssh登录。ganymed-ssh2是一个实现了ssh协议的开源项目,项目地址为:http://ganymed-ssh-2.googlecode.com/ (下载源码要翻强,众所周知的原因),如果只是使用的话,pom.xml添加以下依赖项就行了:
1 <dependency>
2 <groupId>ch.ethz.ganymed</groupId>
3 <artifactId>ganymed-ssh2</artifactId>
4 <version>262</version>
5 </dependency>
为了方便起见,封装了一个工具类SSHUtil.java(已托管在taobao.org上)
package com.cnblogs.yjmyzz.utils;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* SSH工具类(可远程执行其它Linux机器上的Shell命令)
* Created by jimmy on 2015/7/6.
* http://code.taobao.org/p/y-lib/src/trunk/src/main/java/com/cnblogs/yjmyzz/utils/SSHUtil.java
*/
public class SSHUtil {
/**
* 连接到主机
*
* @param hostname
* @param username
* @param password
* @return
* @throws Exception
*/
private static Connection getConnection(String hostname, String username, String password) throws Exception {
Connection conn = null;
try {
conn = new Connection(hostname);
conn.connect();
boolean isAuthenticated = conn.authenticateWithPassword(username, password);
if (isAuthenticated == false) {
throw new IOException("Authentication failed.");
}
} catch (Exception e) {
throw new IOException("username or password error.");
}
return conn;
}
/**
* 执行远程命令
*
* @param hostname 远程主机IP
* @param username 用户名
* @param password 密码
* @param command 需要执行的命令
* @param timeout 超时时间(秒)
* @return
* @throws Exception
*/
public static String execRemoteCommand(String hostname, String username, String password, String command, long timeout)
throws Exception {
Connection conn = getConnection(hostname, username, password);
StringBuilder sb = new StringBuilder();
Session session = null;
try {
session = conn.openSession();
session.requestPTY("vt100", 80, 24, 640, 480, null);
session.execCommand(command);
InputStream stdout = new StreamGobbler(session.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
long start = System.currentTimeMillis();
char[] arr = new char[512];
int read;
int i = 0;
while (true) {
read = br.read(arr, 0, arr.length);
if (read < 0 || (System.currentTimeMillis() - start) > timeout * 1000) {
break;
}
sb.append(new String(arr, 0, read));
i++;
}
} finally {
if (session != null) {
session.close();
}
if (conn != null) {
conn.close();
}
}
return sb.toString();
}
/**
* 执行远程命令(默认5秒超时)
*
* @param hostname 远程主机IP
* @param username 用户名
* @param password 密码
* @param command 需要执行的命令
* @return
* @throws Exception
*/
public static String execRemoteCommand(String hostname, String username, String password, String command)
throws Exception {
return execRemoteCommand(hostname, username, password, command, 5);
}
/**
* 批量执行远程命令
*
* @param hostname 远程主机IP
* @param username 用户名
* @param password 密码
* @param command 需要执行的命令列表
* @param timeout 超时时间(秒)
* @return
* @throws Exception
*/
public static String execRemoteCommand(String hostname, String username, String password, String[] command, long timeout)
throws Exception {
Connection conn = getConnection(hostname, username, password);
StringBuilder sb = new StringBuilder();
Session session = null;
try {
for (int t = 0; t < command.length; t++) {
session = conn.openSession();
session.requestPTY("vt100", 80, 24, 640, 480, null);
session.execCommand(command[t]);
InputStream stdout = new StreamGobbler(session.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
long start = System.currentTimeMillis();
char[] arr = new char[512];
int read;
int i = 0;
while (true) {
read = br.read(arr, 0, arr.length);
if (read < 0 || (System.currentTimeMillis() - start) > timeout * 1000) {
break;
}
sb.append(new String(arr, 0, read));
i++;
}
session.close();
}
} finally {
if (conn != null) {
conn.close();
}
}
return sb.toString();
}
/**
* 批量执行远程命令(默认5秒超时)
*
* @param hostname 远程主机IP
* @param username 用户名
* @param password 密码
* @param command 需要执行的命令列表
* @return
* @throws Exception
*/
public static String execRemoteCommand(String hostname, String username, String password, String[] command)
throws Exception {
return execRemoteCommand(hostname, username, password, command, 5);
}
}
使用要点:
1. 如果要连续执行多个命令,用&&连接,比如:先 cd / 切换到根目录,然后再ls 根目录下的所有文件,可以这样调用:
public static void main(String[] args) {
String hostname = "172.21.129.**";
String username = "root";
String password = "***";
try {
System.out.println(SSHUtil.execRemoteCommand(hostname, username, password,
"pwd&&cd /&&pwd&&ls"));
} catch (Exception e) {
e.printStackTrace();
}
}
上面的命令相当于在同一个session下,连续执行
pwd
cd /
pwd
ls
2. 如果要以后台进程调用命令,传入命令时,直接加 nohup 即可
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PHP变量覆盖漏洞小结
- 算法复习 : 插入排序原理,记忆,时间复杂度 (7行java实现)
- PHP代码审计01之in_array()函数缺陷
- 分治思想 : 并归排序与其时间复杂度
- java Spring系列之 配置文件的操作 +Bean的生命周期+不同数据类型的注入简析+注入的原理详解+配置文件中不同标签体的使用方式
- 算法系列1 初识算法 算法复杂性模型 算法复杂度的计算
- 树莓派基础实验32:DS1302实时时钟模块实验
- Failed to parse date ["1534467411000"]:Invalid time zone indicator '0'
- 快速排序 : 调优:3亿数据40秒,2亿数据30秒,1亿数据15秒
- Spring系列之新注解配置+Spring集成junit+注解注入
- Spring系列之aAOP AOP是什么?+xml方式实现aop+注解方式实现aop
- 线上工程启动日志不滚动了——通过查看堆栈信息排查的过程(ES批量插入)
- Java中使用方法的注意事项
- 微信小程序转发朋友圈详解
- Error: Protocol error, got "H" as reply type byte