2012-03-29 24 views
6

Me pregunto si hay alguna forma de ejecutar el siguiente script de shell, que espera la entrada del usuario utilizando la clase Runtime de java.¿Cómo ejecutar un script de shell interactivo usando java Runtime?

#!/bin/bash 

echo "Please enter your name:" 
read name 
echo "Welcome $name" 

Estoy usando el siguiente código de Java para hacer esta tarea pero solo muestra la consola en blanco.

public class TestShellScript { 
public static void main(String[] args) { 

     File wd = new File("/mnt/client/"); 
      System.out.println("Working Directory: " +wd); 
      Process proc = null; 

      try { 
       proc = Runtime.getRuntime().exec("sudo ./test.sh", null, wd); 

      } catch (Exception e) { 
      e.printStackTrace(); 
      } 


} 

}

La cosa es que cuando ejecuto anterior programa, yo creía que ejecutará un script de shell y que shell script esperará a la entrada del usuario, pero sólo imprime el directorio actual y luego se cierra. ¿Hay alguna manera de hacer esto o no es posible en java?

Gracias de antemano

+0

http://stackoverflow.com/questions/4784789/call-interactive -perl-script-from-java –

Respuesta

1

La razón por la que imprime el directorio actual y sale es porque sus salidas de aplicaciones Java. Es necesario añadir un oyente (roscado) a los flujos de entrada y de error de su proceso de creación, y es probable que desee añadir un PrintStream al flujo de salida del proceso

ejemplo:



      proc = Runtime.getRuntime().exec(cmds); 
      PrintStream pw = new PrintStream(proc.getOutputStream()); 
      FetcherListener fl = new FetcherListener() { 

       @Override 
       public void fetchedMore(byte[] buf, int start, int end) { 
        textOut.println(new String(buf, start, end - start)); 
       } 

       @Override 
       public void fetchedAll(byte[] buf) { 
       }   
      }; 
      IOUtils.loadDataASync(proc.getInputStream(), fl); 
      IOUtils.loadDataASync(proc.getErrorStream(), fl); 
      String home = System.getProperty("user.home"); 
      //System.out.println("home: " + home); 
      String profile = IOUtils.loadTextFile(new File(home + "/.profile")); 
      pw.println(profile); 
      pw.flush(); 

Para ejecutar esto, necesitarás descargar mi proyecto de sourceforge: http://tus.sourceforge.net/ pero espero que el fragmento de código sea lo suficientemente instructivo como para que puedas adaptarlo a J2SE y a cualquier otra cosa que estés usando.

+0

¿Puede publicar algún código de ejemplo o enlace de página web explicando eso con ejemplos en detalle? –

+0

Aquí hay un código que demuestra: – ControlAltDel

+0

He intentado con su código y descargando su fuente de SVN, lo que sucede es que espera la entrada y también puedo escribir la entrada en la consola, pero nunca pasa esa entrada al script de shell y los programas mantienen en ejecución. Lo ideal es cómo debe comportarse después de ingresar el nombre del script del shell, debe imprimir el nombre y el programa debe ejecutarse. –

1

Si usa Java ProcessBuilder, debe poder obtener los flujos de entrada, error y salida del proceso que crea.

Estas transmisiones se pueden utilizar para obtener información que sale del proceso (como solicitudes de entrada) pero también se pueden escribir para incluir información en el proceso directamente. Por ejemplo:

InputStream stdout = process.getInputStream(); 
BufferedReader reader = new BufferedReader (new InputStreamReader(stdout)); 

String line; 
while(true){ 
    line = reader.readLine(); 
    //... 

Eso le dará la salida del proceso directamente. No lo he hecho yo mismo, pero estoy bastante seguro de que process.getOutputStream() le da algo que se puede escribir directamente para enviar información al proceso.

1

El problema con la ejecución de programas interactivos, como sudo, desde Runtime.exec es que conecta su stdin y stdout a las tuberías en lugar del dispositivo de consola que necesitan. Puede hacer que funcione por redirecting the input and output to /dev/tty.

Puede lograr el mismo comportamiento utilizando la nueva clase ProcessBuilder, configurando la redirección usando ProcessBuilder.Redirect.INHERIT.

0

Nota: de ninguna manera puede enviar entradas a su script desde Java. Sin embargo, yo recomiendo muy fuertemente a echar un vistazo a los Comunes Exec si va a ejecutar secuencias de comandos externos de Java:

Commons Exec homepage

Commons Exec API

Cuestiones relacionadas