我无法通过Jsch

时间:2016-09-03 20:16:52

标签: java linux shell jsch

我正在尝试执行以下java代码来执行存储在远程服务器上的shell脚本。当我在shell脚本中包含echo stat | nc hostname 2181时,我的代码工作正常。但是当我删除上面的命令时,我的代码就会卡住,因为它显示连接到主机名而没有显示任何内容。如果我尝试直接在代码中执行echo stat | nc hostname 2181命令,那么它显示“字符串索引超出范围”可以任何人帮助。将不胜感激。

由于我的主持人是一名动物园管理员,我知道echo stat的状态,但包括我还想使用echo打印bytes_in_per_second。如果我同时包含这两个命令,但是如果我删除了echo stat | nc hostname 2181,那么它就不起作用了。

下面是代码,我在远程服务器上编写了shell脚本。

import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.io.IOUtils;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;

public class Conn {

public static void main(String[] args) throws IOException {


    try { 
        final String host = "hostname";
        final String username = "username";
        final String password = "password";
        final int port = 22;
        final String hostKey = "no";


        final String command5 ="sh /home/user/metrics.sh"; //This the command I used


        final String openSession1 = openSession1(host, username,password,port, hostKey, command5);



    }catch (Exception ase) {
        System.out.println("Caught an Exception:");
        System.out.println("Error Message:    " + ase.getMessage());
    }              


}

public static final String HOST_KEY_CHECKING = "StrictHostKeyChecking";
public static final String EXCUTE_CHANNEL = "exec";

// --------------------------------------------- ----------------------------- // openSession // ------------------------------------------------ --------------------------

 public static String openSession1(String host, String username,String password, int port, String hostKey, String command5) {

    JSch jsch = new JSch();
    Session session = null;
    Channel channel = null;
    StringBuilder log = new StringBuilder();

    String response = null;


    try {
        session = jsch.getSession(username, host, port);
        session.setPassword(password);
        session.setConfig(HOST_KEY_CHECKING, hostKey);
        session.setConfig("PreferredAuthentications", "publickey,keyboard-interactive,password");
        session.connect();
        // check if connect was successful
        if (session.isConnected()) {
            System.out.println("Connected sucessfully to server :" + host);

             try{
            channel = session.openChannel(EXCUTE_CHANNEL);

            ((ChannelExec) channel).setCommand(command5);
            // channel.setInputStream(System.in);
            channel.setInputStream(null);

            ((ChannelExec) channel).setErrStream(System.err);

            InputStream in = channel.getInputStream();

            channel.connect();  
            response = IOUtils.toString(in);

             }
                catch(Exception e){
                    return e.toString();
                }
        } else {
            System.out.println("Connection Failed" + host);
        }
    } catch (JSchException e) {
        System.out.println("Connection Failed" + host + " Error:" + e.getMessage());
        e.printStackTrace();
    } catch (Exception e) {
        System.out.println("Connection Failed" + host + " Error:" + e.getMessage());
        e.printStackTrace();
    }

    System.out.println( "Sent:"+  response.substring((response.indexOf("Sent: ") + ("Sent: ").length()),
            (response.indexOf("Connections: "))));

    System.out.println( "Received:"+  response.substring((response.indexOf("Received: ") + ("Received: ").length()),
            (response.indexOf("Sent: "))));

    System.out.println( "Connections:"+  response.substring((response.indexOf("Connections: ") + ("Connections: ").length()),
            response.indexOf("Outstanding: ")));



    System.out.println( "Response received :"+  response);
    return response;

}

}

metrics.sh

#!/bin/bash
echo stat | nc hostname 2181
echo bytes_in_per_second

1 个答案:

答案 0 :(得分:0)

  

当你删除产生你要解析的输出的行时,它当然不起作用。

确定此行引发异常“String index out of range:-6”应该是微不足道的:

==> System.out.println( "Sent:"+ response.substring((response.indexOf("Sent: ") + ("Sent: ").length()), (response.indexOf("Connections: "))));

这很困难,因为您捕获了异常并选择仅打印消息。

如果您打印堆栈跟踪,就像写入其他catch块一样,则会包含行号,例如Conn.java:1000。这是你应该使用的方法。

或者最好使用标准JDK运行程序,而不使用外部try / catch块。它将自动打印未捕获异常的堆栈跟踪。您甚至不必学习调试器或使用调试选项进行编译; Java就是那么友好。

响应中不再出现字符串"Sent: ",因为您删除了生成它的命令。这就是导致问题的原因。

您应该始终发布完整的错误消息。你后来承认完整的输出是

Caught an Exception:
Error Message: String index out of range: -6

如果我们知道这一点,您的调试问题可能会更快地被识别出来。