我正在尝试执行以下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
答案 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
如果我们知道这一点,您的调试问题可能会更快地被识别出来。