2010-05-20 9 views
8

Estoy utilizando Java en Windows XP y deseo poder enviar comandos a otro programa como telnet. No quiero simplemente ejecutar otro programa. Quiero ejecutarlo y luego enviar una secuencia de comandos una vez que se está ejecutando. Aquí está mi código de lo que quiero hacer, pero no funciona: (Si descomenta y cambia el comando a "cmd" funciona como se esperaba. Ayuda por favor) Este es un ejemplo simplificado. En producción, se enviarán muchos más comandos, así que por favor no sugiera llamar a "telnet localhost".En Java, envíe comandos a otro programa de línea de comandos

try 
    { 
     Runtime rt = Runtime.getRuntime(); 

     String command = "telnet"; 
     //command = "cmd"; 
     Process pr = rt.exec(command); 

     BufferedReader processOutput = new BufferedReader(new InputStreamReader(pr.getInputStream())); 
     BufferedWriter processInput = new BufferedWriter(new OutputStreamWriter(pr.getOutputStream())); 

     String commandToSend = "open localhost\n"; 
     //commandToSend = "dir\n" + "exit\n"; 

     processInput.write(commandToSend); 
     processInput.flush(); 

     int lineCounter = 0; 
     while(true) 
     { 
      String line = processOutput.readLine(); 
      if(line == null) break; 
      System.out.println(++lineCounter + ": " + line); 
     } 

     processInput.close(); 
     processOutput.close(); 
     pr.waitFor(); 
    } 
    catch(Exception x) 
    { 
     x.printStackTrace(); 
    } 
+0

¿Desea una solución de comunicación entre procesos para Java? – Justin

+0

Me parece que telnet está escribiendo su salida a algo que no sea el flujo de entrada del proceso, y Java no lo está capturando. ¿Es Process.getInputStream() el único método para leer lo que está produciendo un proceso? – bradvido

Respuesta

3

Eso se ve bien, ya que no producirá esa cantidad de salida, pero realmente debe leer y escribir en hilos separados para que no llene el búfer y bloquee la espera de leer antes de llegar al siguiente paso .

Por lo tanto, si llega al punto en el que envía el comando, averigüe si el cliente telnet de Windows admite la recepción de comandos desde una entrada estándar en lugar de una consola transfiriendo el texto que está enviando a su entrada estándar a en un símbolo del sistema.

Por ejemplo, echo dir c:\ | cmd hace que cmd se ejecute, enumere los contenidos de c: drive y salga, casi del mismo comportamiento que si escribiera dir c:\ en la consola. Pero echo open localhost | telnet hace que Telnet borre la pantalla y luego salga, en lugar de comportarse del mismo modo que si lo hubiera escrito en la consola. Como telnet necesita enmascarar la entrada del usuario para las contraseñas, es bastante probable que esté usando el console API en lugar de leer desde la entrada estándar. Es help y no enumera ningún argumento de comando para indicarle que lea de la entrada estándar, por lo que tal vez necesite usar una implementación de telnet que sea más adecuada para la creación de scripts.

+0

Estoy de acuerdo. Este es un ejemplo simplificado para mostrar mi problema, así que lo guardé con un solo hilo. ¿Puedes explicar a qué te refieres con entrada estándar vs. consola y canalizar el texto? – bradvido

+0

@bradvido Bien, 'echo open localhost | telnet' no funciona, pero 'echo dir c: | cmd' sí, entonces sospecho fuertemente que el cliente de Windows telnet está usando la API de la consola para detectar pulsaciones de tecla en lugar de leer su flujo de entrada. –

+0

Veo esto ahora. Este es obviamente el problema con el que me estoy encontrando. ¿Tiene alguna idea de cómo puedo escribir en la consola de una aplicación en lugar de la secuencia de entrada? – bradvido

3

No es directamente una respuesta a su pregunta, pero ...

En lugar de utilizar Runtime.exec() se debe utilizar un ProcessBuilder y redirigir stderr a stdout (ProcessBuilder.redirectErrorStream(true)). De lo contrario, su proceso podría bloquearse si escribe algo en stderr (a Windows no le gusta cuando la salida de un proceso no se lee).

+0

Esto es bastante parecido a una "respuesta directa": puede iniciar el proceso y leer la salida de 'Process.getOutputStream()' y escribir comandos en 'Process.getInputStream()' –

+0

Intenté esto, y me sale el mismo problema . La salida de telent no se lee. El programa se ejecuta sin imprimir nada. – bradvido

+3

Una pequeña corrección a lo que D.Shawley escribió, desde el punto de vista de su código en Java, usted ** leyó ** ** Process.getInputStream() 'y ** write to **' Process.getOutputStream() '...el nombramiento es confuso, aparentemente fueron nombrados desde un punto de vista diferente ... –

2

Si desea controlar una sesión de telnet programáticamente desde Java, puede utilizar este Java telnet library ... puede hacer las mismas cosas (abrir conexiones, enviar nombre de usuario/contraseña, enviar comandos y recibir resultados) pero sin en realidad generando un proceso separado.

+0

El telent era simplemente para un ejemplo. Necesito que esto sea genérico para poder ejecutar cualquier comando ejecutable y escribirlo – bradvido

1

Puede echar un vistazo al Telnet Ant task puede llamarlo directamente en su código sin tener que usar un archivo build.xml.

También puede consultar el source code y ver cómo lo hacen.

Cuestiones relacionadas