zoukankan      html  css  js  c++  java
  • 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     }
    获取流中数据


              

              

  • 相关阅读:
    CodeForces 734F Anton and School
    CodeForces 733F Drivers Dissatisfaction
    CodeForces 733C Epidemic in Monstropolis
    ZOJ 3498 Javabeans
    ZOJ 3497 Mistwald
    ZOJ 3495 Lego Bricks
    CodeForces 732F Tourist Reform
    CodeForces 732E Sockets
    CodeForces 731E Funny Game
    CodeForces 731D 80-th Level Archeology
  • 原文地址:https://www.cnblogs.com/-wangjiannan/p/3751330.html
Copyright © 2011-2022 走看看