2011-06-20 11 views
9

Entonces, tengo esta clase que usa la clase org.apache.commons.net.telnet.TelnetClient. Intenta enviar comandos y leer la respuesta.Cómo deshabilitar echo al enviar un comando de terminal usando apache-commons-net 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(); 
     } 
    } 
} 

Problema es que cuando envío un comando, la respuesta viene precedida de un eco. Por ejemplo, cuando envío el comando ls, esta es la respuesta que leí

[mls 
.... 

He intentado buscar en how to disable echo, pero nadie parece tener la respuesta. Entonces, decidí preguntarle a esta comunidad. ¿Alguien sabe cómo desactivar este eco?

EDITAR

Si examina el código fuente de EchoOptionHandler me es confusa. ¿Por qué los métodos de subnegociación solo devuelven null?

+0

Tal vez podría simplemente eliminarlo a mano utilizando subcadena de la respuesta, ¿no? Saludos, Stéphane – Snicolas

+0

Lo sé, pero esperaba que hubiera un mecanismo disponible en la biblioteca para hacerlo. – mre

Respuesta

5

Problema interesante. Para resumir mi esfuerzo: No he tenido que trabajar adecuadamente pero aquí están algunos de mis hallazgos:

No se puede escribir IAC DON'T ECHO directamente al canal de datos, esto se hace con los comandos y opciones como este ejemplo

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

puede registrar telnet.registerNotifHandler(new MyNotificationHandler()); para depurar los comandos al establecer la conexión

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"; 
    } 
} 
+0

+1, gracias por los consejos, pero desafortunadamente, ¡esto solo ha demostrado que me empuja en la dirección correcta! – mre

3

Por defecto, TelnetClient indica al sistema remoto que se trata de un terminal "VT100". El [m es parte de una secuencia de escape VT100. Al construir el TelnetClient pase "dumb" como primer argumento para indicar que el terminal no admite secuencias de escape. Así

TelnetClient telnet = new TelnetClient("dumb"); 

Actualización:

puede ser el intérprete de comandos en el control remoto está configurado para mostrar en color. Si ejecuta "echo $ PS1" verá lo que el indicador se establece en y que podría ser algo como:

\[\e]2;\[email protected]\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\]]$ 

que aparece en mi terminal como "[directorio de usuario @ host] $" con los soportes y signo de dólar en blanco, el usuario en azul, el host en verde y el directorio en amarillo. Todo muy agradable para las personas, pero malo para las máquinas.

Tan pronto como inicie sesión, envíe "PS1 = '$' \ n". Eso establecerá la solicitud exactamente en un signo de dólar seguido de un espacio sin secuencias adicionales.

+1

que no ayudó. :/ – mre

+0

@little bunny foo foo - Agregué una actualización a mi respuesta –

1

Tenemos este problema también en nuestro uso del java TelnetClient. Es inconsistente si el servidor telnet devuelve el comando enviado en sus respuestas.

Lo que estamos haciendo actualmente para asegurarnos de que el comando no esté incluido en los datos de respuesta es enviar el comando stty a la sesión de telnet para desactivar el eco de terminal. Esto funciona para servidores de telnet que se ejecutan en Linux y si se introduce el comando en el intérprete de comandos bash:

stty -echo

2

Apache está libre de errores. EchoOptionHandler(false, false, false, false) no funciona. En un caso, new TelnetClient("dumb") me ayudó. Otro servidor obedeció solo el comando stty -echo.

0

El comando telnet echo es un comando simple que no requiere subnegociación. Pruebe:

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

Funciona para mí.

Cuestiones relacionadas