Domanda

Ho problemi a interagire con un processo utilizzando getOutputStream.Ecco il mio codice:

    Process p = null;
    ProcessBuilder pb = new ProcessBuilder("/home/eric/this.sh");
    pb.directory(new File("/home/eric/"));
    p = pb.start();

    InputStream in = null;
    OutputStream outS = null;

    StringBuffer commandResult = new StringBuffer();
    String line = null;
    int readInt;

    int returnVal = p.waitFor();

    in = p.getInputStream();

    while ((readInt = in.read()) != -1)
        commandResult.append((char)readInt);
    outS = (BufferedOutputStream) p.getOutputStream();
    outS.write("Y".getBytes());
    outS.close();

    System.out.println(commandResult.toString());
    in.close();

Ecco l'output:

Reading package lists...
Building dependency tree...
Reading state information...
The following packages were automatically installed and are no longer required:
  libmono2.0-cil libmono-data-tds2.0-cil libmono-system-data2.0-cil
  libdbus-glib1.0-cil librsvg2-2.18-cil libvncserver0 libsqlite0
  libmono-messaging2.0-cil libmono-system-messaging2.0-cil
  libmono-system-data-linq2.0-cil libmono-sqlite2.0-cil
  libmono-system-web2.0-cil libwnck2.20-cil libgnome-keyring1.0-cil
  libdbus1.0-cil libmono-wcf3.0-cil libgdiplus libgnomedesktop2.20-cil
Use 'apt-get autoremove' to remove them.
The following extra packages will be installed:
  firefox-globalmenu
Suggested packages:
  firefox-gnome-support firefox-kde-support latex-xft-fonts
The following NEW packages will be installed:
  firefox firefox-globalmenu
0 upgraded, 2 newly installed, 0 to remove and 5 not upgraded.
Need to get 15.2 MB of archives.
After this operation, 30.6 MB of additional disk space will be used.
Do you want to continue [Y/n]? Abort

this.sh esegue semplicemente "gksudo apt-get install firefox"

Non so perché si interrompa e non riceva il mio input "Y", grazie.

È stato utile?

Soluzione

Ci sono diversi problemi.

Primo : gksudo(1) esegue alcuni trucchi sporchi e non standard con lo standard input e standard output dei comandi che avvia. Fallisce in modo orribile. Un buon esempio è questa riga di comando:

$ echo foo | gksudo -g cat

Mi aspetto qualsiasi output e la cessazione del cat non appena il echo ha consegnato i dati. No. Sia gksudo che cat restano in giro per sempre. Nessun output.

Il tuo caso d'uso sarebbe

echo y |gksudo apt-get install ....

e anche questo non funzionerà. Finché il problema non viene risolto, puoi dimenticare di eseguire qualsiasi controllo remoto se il programma avviato richiede l'input dell'utente.

Secondo : come già sottolineato da Roger waitFor() attende la fine del comando. Questo non accadrà presto senza alcun input da parte dell'utente e con il problema di gksudo.

Terzo Dopo aver spinto waitFor un po 'in basso, c'è il blocco successivo: aspetti l'output completo del processo fino all'EOF incluso. Ciò non accadrà presto (vedere "primo" e "secondo").

Quarto Solo dopo che il processo è già morto due volte (vedere "secondo" e "terzo") potrebbe ricevere un input: il tuo Y (che potrebbe anche richiedere un \n aggiuntivo).


Invece di risolvere questo mucchio di problemi, potrebbe esserci un modo migliore e molto più semplice: non provare a controllare apt-get install con lo standard input. Dagli solo alcune opzioni appropriate che "rispondono" automaticamente alle tue domande. Un rapido man apt-get mostra alcuni candidati:

-y, --yes, --assume-yes
--force-yes
--trivial-only
--no-remove
--no-upgrade

Vedere il manuale per i dettagli.

Penso che questo sia il modo migliore e più stabile.

PS: In questo momento sono un po 'più gksudo, quindi scusa lo sfogo sopra.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top