使用apache-commons-net TelnetClient发送终端命令时如何禁用echo

所以,我有这个使用org.apache.commons.net.telnet.TelnetClient类的类。 它尝试发送命令并读取响应。

 public class AutomatedTelnetClient { private TelnetClient telnet = new TelnetClient(); private InputStream in; private PrintStream out; private String prompt = "$"; public AutomatedTelnetClient(String server, String user, String password) { try { EchoOptionHandler echoopt = new EchoOptionHandler(false, false, false, false); telnet.addOptionHandler(echoopt); // Connect to the specified server telnet.connect(server, 23); // Get input and output stream references in = telnet.getInputStream(); out = new PrintStream(telnet.getOutputStream()); // Log the user on readUntil("login: "); write(user); readUntil("Password: "); write(password); // Advance to a prompt readUntil(prompt + " "); } catch (Exception e) { e.printStackTrace(); } } public void su(String password) { try { write("su"); readUntil("Password: "); write(password); prompt = "#"; readUntil(prompt + " "); } catch (Exception e) { e.printStackTrace(); } } public String readUntil(String pattern) { try { char lastChar = pattern.charAt(pattern.length() - 1); StringBuffer sb = new StringBuffer(); boolean found = false; char ch = (char) in.read(); while (true) { System.out.print(ch); sb.append(ch); if (ch == lastChar) { if (sb.toString().endsWith(pattern)) { return sb.toString(); } } ch = (char) in.read(); } } catch (Exception e) { e.printStackTrace(); } return null; } public void write(String value) { try { out.println(value); out.flush(); System.out.println(value); } catch (Exception e) { e.printStackTrace(); } } public String sendCommand(String command) { try { write(command); return readUntil(prompt + " "); } catch (Exception e) { e.printStackTrace(); } return null; } public void disconnect() { try { telnet.disconnect(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { try { AutomatedTelnetClient telnet = new AutomatedTelnetClient( "...", "...", "..."); System.out.println("Got Connection..."); System.out.println("run command"); telnet.sendCommand("ls "); telnet.sendCommand("cd netConf"); telnet.sendCommand("ls "); telnet.sendCommand("cd lanSetup"); telnet.sendCommand("ls "); telnet.sendCommand("cd dhcpd"); telnet.sendCommand("show interface 2"); telnet.disconnect(); System.out.println("DONE"); } catch (Exception e) { e.printStackTrace(); } } } 

麻烦的是,当我发送命令时,响应的前面是各种回声。 例如,当我发送ls命令时,这是我读过的响应

 [mls .... 

我试过搜索如何禁用回声 ,但没有人似乎有答案。 所以,我决定问这个社区。 有谁知道如何禁用这个回声?

编辑

查看EchoOptionHandler的源代码令我感到困惑。 为什么子协商方法只返回null

有趣的问题。 总结一下我的努力:我没有让它正常工作但是这里有一些我的发现:

您无法将IAC DON'T ECHO直接写入数据通道,这可以通过此示例中的命令和选项完成

 int[] msg = {TelnetCommand.DONT,TelnetOption.ECHO}; telnet.sendSubnegotiation(msg); 

你可以注册telnet.registerNotifHandler(new MyNotificationHandler()); 在连接设置期间调试命令

 public class MyNotificationHandler implements TelnetNotificationHandler { @Override public void receivedNegotiation(int negotiation_code, int option_code) { System.out.println("--->"+get(negotiation_code)+" " +TelnetOption.getOption(option_code)); } private String get(int i) { if(i==TelnetNotificationHandler.RECEIVED_DO){return "RECEIVED_DO";} else if(i==TelnetNotificationHandler.RECEIVED_DONT){return "RECEIVED_DONT";} else if(i==TelnetNotificationHandler.RECEIVED_WILL){return "RECEIVED_WILL";} else if(i==TelnetNotificationHandler.RECEIVED_WONT){return "RECEIVED_WONT";} else if(i==TelnetNotificationHandler.RECEIVED_COMMAND) {return "RECEIVED_COMMAND";} return "UNKNOWN"; } } 

默认情况下,TelnetClient向远程系统指示它是“vt100”终端。 [m是VT100转义序列的一部分。 构造TelnetClient传递"dumb"作为第一个参数,表明终端不支持转义序列。 所以

 TelnetClient telnet = new TelnetClient("dumb"); 

更新:

可能是遥控器上的shell提示符设置为彩色显示。 如果你运行“echo $ PS1”,你会看到提示设置的内容,它可能是这样的:

 \[\e]2;\u@\h : \w\007\]\[\e[39m\e[0;49m\][\[\e[1;34m\]\u\[\e[0;37m\]@\[\e[0;32m\]\h\[\e[0;36m\] \[\e[0;33m\]\w\[\e[39m\e[0;49m\]]$ 

在我的终端上显示为“[user @ host directory] ​​$”,括号和美元符号为白色,用户为蓝色,主机为绿色,目录为黄色。 一切都非常适合人,但对机器不利。

登录后,立即发送“PS1 =’$’\ n”。 这会将提示设置为一个美元符号,后跟一个没有任何额外序列的空格。

你查过expect4J了吗?

url – http://code.google.com/p/expect4j

这实际上是expect库的java实现。

Apache有缺陷。 EchoOptionHandler(false, false, false, false)不起作用。 在一个案例中, new TelnetClient("dumb")帮助了我。 另一台服务器只服从stty -echo命令。

我们在使用java TelnetClient时也遇到了这个问题。 telnet服务器是否在其响应中返回sent命令是不一致的。

我们目前正在做的是确保命令不包含在响应数据中是将stty命令发送到telnet会话以关闭终端回显。 这适用于在linux上运行的telnet服务器,如果在bash shell中输入命令:

stty -echo

telnet echo命令是一个简单的命令,不需要子协商。 尝试:

 telnet.sendCommand((byte)(TelnetCommand.DONT | TelnetOption.ECHO)); 

这个对我有用。