实际应用中,有时候需要从web管理界面上,远程去启动其它linux主机上的程序,利用ssh协议可以方便的满足这一需求。事实上hadoop架构中,从nn上启动dn时,就是利用了免密码ssh登录。ganymed-ssh2是一个实现了ssh协议的开源项目,项目地址为:http://ganymed-ssh-2.googlecode.com/ (下载源码要翻强,众所周知的原因),如果只是使用的话,pom.xml添加以下依赖项就行了:

         <dependency>
<groupId>ch.ethz.ganymed</groupId>
<artifactId>ganymed-ssh2</artifactId>
<version>262</version>
</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 即可 

  

利用ganymed-ssh2远程执行其它Linux机器上的shell命令的更多相关文章

  1. 在Linux机器上安装telnet命令

    一.查看本机是否安装       telnet #rpm -qa | grep telnet     如果什么都不显示,说明没有安装telnet 二.开始安装 yum install xinetd y ...

  2. 如何将项目部署到远程的Linux机器上的tomcat上

    下面来练习一下如何将本地的一个项目部署到远程的Linux机器上去. 第一步:将要部署到Linux机器上的项目打成一个war包 war包有一个好处tomcat可以自动解压 第二步:将打好的war上传到L ...

  3. 在Linux机器上安装MySQL

    在Linux机器上安装MySQL,仔细认真些就没有问题. CentOS 7下MySQL 5.7安装.配置与应用_数据库技术_Linux公社-Linux系统门户网站 搞不定的话,直接删掉这个MySQL, ...

  4. linux机器上部署多台Tomcat

    在Linux机器上部署多台Tomcat, 我部署的是Tomcat8,只需要一步,即避免端口号冲突. 在解压后的tomcat目录下,修改conf下server.xml. 修改shutdown端口: &l ...

  5. Linux不管上一条命令成功还是失败都执行下一个命令的方法

    转载请注明来源https://www.cnblogs.com/sogeisetsu/p/11407830.html Linux不管上一条命令成功还是失败都执行下一个命令的方法 Linux不管上一条命令 ...

  6. linux服务器上没有jar命令

    在linux服务器上用jar命令解压jar包时,提示找不到jar命令. 但是用java -version查看jdk版本,又可以显示出jdk版本. echo $JAVA_HOME查看环境变量路径,找不到 ...

  7. java调用机器上的shell脚本

    java调用机器上的shell脚本,可以这样方便的通过shell脚本调用本机的C.C++等程序 Process process = null; Runtime runTime = Runtime.ge ...

  8. linux系统上传下载命令rz和sz的教程

    (一)安装方法汇总(注意:一下命令如果没有权限的需要在每个命令前面加一个sudo) 1.安装方法(推荐) sudo yum install lrzsz 2.在安装Linux系统时选中“DialupNe ...

  9. linux利用ssh远程执行多台机器执行同样的命令

    这篇文章主要介绍了ssh远程执行命令方法和Shell脚本实例,本文讲解了ssh执行远程操作方法和远程执行命令shell脚本示例,需要的朋友可以参考下 ssh执行远程操作命令格式代码如下: ssh -t ...

随机推荐

  1. Play Framework 完整实现一个APP(二)

    1.开发DataModel 在app\moders 下新建User.java package models; import java.util.*; import javax.persistence. ...

  2. 《java JDK7学习笔记》之跨平台与路径设置

    Platforms表示Solaris.Linux.Windows各种操作系统平台,在这些平台上架构了java Virtaul Machine,简称JVM,Java虚拟机. Java虚拟机可以让java ...

  3. Linux计时器

    Linux中, 系统为每个系统都维护了三种计时器,分别为: 真实计数器, 虚拟计时器以及实用计时器, 一般情况下都使用真实计时器 getitimer()/setitimer() //读取/设置内部计时 ...

  4. (转)Yii的组件机制之一:组件基础类CComponent分析

    Yii的组件机制 组件机制,是Yii整个体系的思想精髓,在使用Yii之前,最应该先了解其组件机制,如果不了解这个机制,那么阅读Yii源代码会非常吃力.组件机制给Yii框架赋予了无穷的灵活性和可扩展性, ...

  5. Java【小考】

    课上, 老师出了一个题: 考察:1.类的定义 2.类的属性 3.类的方法.重载.构造方法.代码块 题目是这样的: 设计 一个 类:Tree 要求: 1.包含main方法 2.属性:静态: String ...

  6. PHP正确的使用复数

    <?php // 正确地显示复数 if(!function_exists('_plurals_format')) { /** * 正确的使用复数 * @access public * @auth ...

  7. xsd.exe的使用

    xsd.exe的使用 XML文件生成XSD文件 xsd myFile.xml   /outputdir:myOutputDir XSD文件生存实体类 xsd <你的XSD路径>.xsd / ...

  8. [转]ASP.Net篇之Session与Cookie

    本文转自:http://www.cnblogs.com/japanbbq/archive/2011/08/31/2160494.html Session: Session是“会话”的意思,然而,因为h ...

  9. 模版(template)

    模版(template) 在c++Template中很多地方都用到了typename与class这两个关键字,而且好像可以替换,是不是这两个关键字完全一样呢? 相信学习C++的人对class这个关键字 ...

  10. AC日记——字符串的展开 openjudge 1.7 35

    35:字符串的展开 总时间限制:  1000ms 内存限制:  65536kB 描述 在初赛普及组的“阅读程序写结果”的问题中,我们曾给出一个字符串展开的例子:如果在输入的字符串中,含有类似于“d-h ...