Pregunta

Tengo problemas para interactuar con un proceso usando getOutputStream.Aquí está mi código:

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

Aquí está el resultado:

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 simplemente ejecuta "gksudo apt-get install firefox"

No sé por qué se cancela y no se acepta mi entrada "Y", gracias.

¿Fue útil?

Solución

Hay varios problemas.

Primero: gksudo(1) hace algunos trucos sucios y no estándar con la entrada estándar y la salida estándar de los comandos que inicia.Falla horrible.Un buen ejemplo es esta línea de comando:

$ echo foo | gksudo -g cat

Esperaría cualquier resultado y la terminación del cat tan pronto como echo ha entregado los datos.No.Ambos gksudo y cat quedarse para siempre.Ninguna salida.

Su caso de uso sería

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

y esto tampoco funcionará.Mientras esto no se resuelva, puede olvidarse de realizar cualquier control remoto si el programa iniciado requiere alguna intervención del usuario.

Segundo:Como ya señaló Roger waitFor() espera la terminación del comando.Esto no sucederá pronto sin la participación del usuario y con el problema de gksudo.

Tercero despues de empujar waitFor Un poco más abajo está el siguiente bloqueador:esperas por el completo salida del proceso hasta e incluyendo el EOF.Esto no sucederá pronto (ver "primero" y "segundo").

Cuatro Sólo después de que el proceso ya haya muerto dos veces (ver "segundo" y "tercero") podría recibir alguna información: su Y (que también podría necesitar un adicional \n).


En lugar de resolver este montón de problemas, podría haber una manera mejor y mucho más sencilla:No intentes controlar apt-get install con entrada estándar.Simplemente dale algunas opciones apropiadas que "respondan" automáticamente a tus preguntas.Un rápido man apt-get presenta algunos candidatos:

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

Consulte el manual para obtener más detalles.

Creo que esta es la forma mejor y más estable.

PD:Ahora mismo estoy cabreado gksudo bastante, así que disculpe la perorata anterior.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top