Java远程执行Shell命令

1. Jar包:ganymed-ssh2-build210.jar

2. 步骤:

  a) 连接:

    Connection conn = new Connection(ipAddr);

    conn.connect();

  b)认证:

    boolean authenticateVal = conn.authenticateWithPassword(userName,
password);

c) 打开一个Session:

    if(authenticateVal)

      Session session = conn.openSession();

  d) 执行Shell命令:

       1)若是执行简单的Shell命令:(如 jps 、last 这样的命令 )

        session.execCommand(cmd);

       2) 遇到问题:

          用方法execCommand执行Shell命令的时候,会遇到获取不全环境变量的问题,

          比如执行 hadoop fs -ls 可能会报找不到hadoop 命令的异常

          试着用execCommand执行打印环境变量信息的时候,输出的环境变量不完整

          与Linux主机建立连接的时候会默认读取环境变量等信息

          可能是因为session刚刚建立还没有读取完默认信息的时候,execCommand就执行了Shell命令

        解决:

        所以换了另外一种方式来执行Shell命令:

          // 建立虚拟终端

          session.requestPTY("bash");

          // 打开一个Shell

          session.startShell();

          // 准备输入命令

          PrintWriter out = new
PrintWriter(session.getStdin());
      
         
      
              // 输入待执行命令

          out.println(cmd);

          out.println("exit")

          // 6. 关闭输入流

          out.close();

          // 7. 等待,除非1.连接关闭;2.输出数据传送完毕;3.进程状态为退出;4.超时

          session.waitForCondition(ChannelCondition.CLOSED |
ChannelCondition.EOF | ChannelCondition.EXIT_STATUS , 30000);

        用这种方式执行Shell命令,会避免环境变量读取不全的问题,第7步里有许多标识可以用,比如当exit命令执行后或者超过了timeout时间,则session关闭  

        这里需要注意,当一个Shell命令执行时间过长时,会遇到ssh连接超时的问题,

        解决办法:

          1. 之前通过把Linux主机的sshd_config的参数ClientAliveInterval设为60,同时将第7步中timeout时间设置很大,来保证命令执行完毕,

           
因为是执行Mahout中一个聚类算法,耗时最少7、8分钟,数据量大的话,需要几个小时。

          2. 
后来将命令改成了nohup的方式执行,nohup hadoop jar .... >> XXX.log && touch
XXX.log.end &

           
这种方式是提交到后台执行,即使当前连接断开也会继续执行,把命令的输出结果写入日志,如果hadoop命令执行成功,则生成.end文件

           
获取文件的方法 ganymed-ssh2-build210.jar 也提供了,如下

              SCPClient
scpClient = con.createSCPClient();

              scpClient.get("remoteFiles","localDirectory"); 
//从远程获取文件

  
e)
获取Shell命令执行结果:

    InputStream
stderr = new StreamGobbler(session.getStderr());

    InputStream
in = new StreamGobbler(session.getStdout());


 1 private String processStdErr(InputStream in, String charset)
2 throws IOException {
3 BufferedReader br = new BufferedReader(new InputStreamReader(in, charset));
4 StringBuffer sb = new StringBuffer();
5
6 if (in.available() != 0) {
7 while (true) {
8 String line = br.readLine();
9 if (line == null)
10 break;
11 sb.append(line).append(System.getProperty("line.separator"));
12 }
13 }
14
15 return sb.toString();
16 }

获取流中数据

          

Java远程执行Shell命令,布布扣,bubuko.com

时间: 2024-09-24 17:36:39

Java远程执行Shell命令的相关文章

Linux远程执行shell命令

Linux远程执行shell命令 在Linux系统中,我们经常想在A机器上,执行B机器上的SHELL命令. 下面这种方案,是一种流行可靠的方案. 1.SSH无密码登录 # 本地服务器执行(A机器):生成密钥对 ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa # 远程服务器执行(B机器):用公钥给远程机器授权,首先需要将本地公钥拷贝到远程服务器上,远程机器授权全后,可以删除公钥 cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized

Linux远程执行Shell命令或脚本

## 远程执行shell命令 ssh [user]@[server] '[command]' # eg. ssh [email protected]192.168.1.1 'uptime' ## 远程执行本地shell脚本 ssh [user]@[server] 'bash -s' < [local_script] # eg. ssh [email protected]192.168.1.1 'bash -s' < local_script.sh

Android JAVA代码执行shell命令

Android中级篇之用JAVA代码执行shell命令 [日期:2011-12-08] 来源:Linux社区  作者:y13872888163    在Android可能有的系统信息没有直接提供API接口来访问,为了获取系统信息时我们就要在用shell指令来获取信息,这时我们可以在代码中来执行命令 ,这里主要用到ProcessBuilder 这个类. 代码部分  : 1.package com.yin.system_analysis; 2.import java.io.File; 3.impor

JAVA远程执行Shell脚本类

1.java远程执行shell脚本类 1 package com.test.common.utility; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.io.UnsupportedEncodingException; 6 import java.nio.charset.Charset; 7 8 import org.apache.commons.io.IOUtils; 9 import o

Java SSH远程执行Shell命令、shell脚本实现(Ganymed SSH)

jar包下载地址: http://www.ganymed.ethz.ch/ssh2/ 此源码的好处就是没有依赖很多其他的包,拷贝过来干干净净.具体代码实现可以看下文,或参考官方文档,在下载的压缩包里ganymed-ssh2-build210\examples目录下有示例. package com.system.action; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream;

通过Java代码执行shell命令/脚本

JDK自带的两种方式有通过Runtime.getRuntime().exec()和ProcessBuilder类来做, 后者是JDK1.5以后引入的,官方也建议放弃使用Runtime的方式来做.今天在实现的时候就是采用ProcessBuilder,apache commons类库也提供了一个exec包专门做这类功能,这次暂时没用到. 在编写过程中,遇到几个比较坑的地方: 1.构建ProcessBuilder采用的参数: 建议采用"/bin/bash". "-c",

Java 实现 ssh命令 登录主机执行shell命令

Java 实现 ssh命令 登录主机执行shell命令 1.SSH命令 SSH 为 Secure Shell 的缩写,由 IETF 的网络小组(Network Working Group)所制定:SSH 为建立在应用层基础上的安全协议.SSH 是较可靠,专为远程登录会话和其他网络服务提供安全性的协议.利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题.SSH最初是UNIX系统上的一个程序,后来又迅速扩展到其他操作平台.SSH在正确使用时可弥补网络中的漏洞.SSH客户端适用于多种平台.几乎

java执行shell命令,chmod 777 xxx,改变权限无效的解决办法。

在java程序中执行shell命令,改变文件的权限,可以在命令行中执行 chmod 777 <span style="font-family: Arial, Helvetica, sans-serif;">/data/misc/123.sh"</span> 来改变权限,但是在java代码中执行这个命令时使用 Runtime.getRuntime().exec("chmod 777 /data/misc/123.sh"): 无效,使用

Java程序执行Linux命令(JSP运行其他程序)

java程序中要执行linux命令主要依赖2个类:Process和Runtime 首先看一下Process类: ProcessBuilder.start() 和 Runtime.exec 方法创建一个本机进程,并返回 Process 子类的一个实例,该实例可用来控制进程并获得相关信息.Process 类提供了执行从进程输入.执行输出到进程.等待进程完成. 检查进程的退出状态以及销毁(杀掉)进程的方法. 创建进程的方法可能无法针对某些本机平台上的特定进程很好地工作,比如,本机窗口进程,守护进程,M