2012-03-29 17 views
6

Mi chiedo se esista un modo per eseguire il seguente script di shell, che attende l'input dell'utente usando la classe Runtime di java?Come eseguire uno script di shell interattivo usando java runtime?

#!/bin/bash 

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

Sto usando il seguente codice java per eseguire questa operazione ma mostra solo una console vuota.

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(); 
      } 


} 

}

cosa è quando eseguo sopra programma, ho creduto che eseguirà uno script di shell e script di shell che attenderà l'input dell'utente, ma esso stampa solo directory corrente e poi esce. C'è un modo per fare questo o non è possibile a tutti in Java?

Grazie in anticipo

+0

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

risposta

1

Il motivo per cui stampa la directory corrente ed esce è perché le vostre uscite java app. È necessario aggiungere un (filettata) ascoltatore ai flussi di ingresso e di errore del vostro processo creato, e probabilmente si vorrà aggiungere un PrintStream al flusso di output del processo

esempio:



      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(); 

Per eseguire questo, dovrai scaricare il mio progetto sourceforge: http://tus.sourceforge.net/ ma si spera che lo snippet di codice sia sufficientemente istruttivo da poter essere adattato a J2SE e qualsiasi altra cosa tu stia utilizzando.

+0

Puoi pubblicare alcuni esempi di codice o link di pagine web che spiegano che con esempi in dettaglio. –

+0

ecco un codice che dimostra: – ControlAltDel

+0

Ho provato con il tuo codice e scaricato la tua fonte da SVN, quello che succede è in attesa di input e anche io sono in grado di digitare input su console, ma non passa mai quell'input allo shell script e programmi keep sull'esecuzione. Idealmente, come dovrebbe comportarsi, dopo aver inserito il nome, lo script della shell dovrebbe stampare il nome e il programma dovrebbe essere eseguito. –

1

Se si utilizza un ProcessBuilder Java, è possibile ottenere i flussi di input, di errore e di output del processo creato.

Questi flussi possono essere utilizzati per ottenere informazioni che escono dal processo (come prompt per l'input) ma possono anche essere scritti per inserire direttamente le informazioni nel processo. Ad esempio:

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

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

Questo ti darà l'output direttamente dal processo. Non l'ho fatto da solo, ma sono abbastanza sicuro che lo process.getOutputStream() ti fornisca qualcosa che può essere scritto direttamente per inviare input al processo.

1

Il problema con l'esecuzione di programmi interattivi, ad esempio sudo, da Runtime.exec è che allega i loro stdin e stdout alle pipe anziché al dispositivo console di cui hanno bisogno. Puoi farlo funzionare con redirecting the input and output to /dev/tty.

È possibile ottenere lo stesso comportamento utilizzando la nuova classe ProcessBuilder, impostando il reindirizzamento utilizzando ProcessBuilder.Redirect.INHERIT.

0

Nota sicuramente è possibile inviare input allo script da Java. Comunque vi consiglio fortemente di avere uno sguardo a Commons Exec se si sta per eseguire script esterni da Java:

Commons Exec homepage

Commons Exec API

Problemi correlati