Pergunta

Estou tendo problemas para interagir com um processo usando getOutputStream.Aqui está meu 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();

Aqui está o 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 simplesmente executa "gksudo apt-get install firefox"

Não sei por que está Abortando e não aceitando minha entrada "S", obrigado.

Foi útil?

Solução

Existem vários problemas.

Primeiro : gksudo(1) faz alguns truques sujos e não padrão com a entrada e saída padrão dos comandos que inicia. Ele falha horrivelmente. Um bom exemplo é esta linha de comando:

$ echo foo | gksudo -g cat

Eu esperaria qualquer saída e o encerramento do cat assim que o echo entregasse os dados. Não. gksudo e cat perduram para sempre. Sem saída.

Seu caso de uso seria

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

e isso também não funcionará. Enquanto isso não for resolvido, você pode esquecer de fazer qualquer controle remoto se o programa iniciado exigir alguma entrada do usuário.

Segundo : Como já apontado por Roger, waitFor() aguarda o término do comando. Isso não vai acontecer tão cedo, sem qualquer entrada do usuário e com o problema do gksudo.

Terceiro Depois de empurrar waitFor um pouco para baixo, há o próximo bloqueador: você espera pela saída completa do processo até e incluindo o EOF. Isso não acontecerá tão cedo (veja "primeiro" e "segundo").

Quarto Somente depois que o processo já estiver morto duas vezes (consulte "segundo" e "terceiro"), ele pode receber alguma entrada - seu Y (que também pode precisar de um \n adicional).


Em vez de resolver esse monte de problemas, pode haver uma maneira melhor e muito mais fácil: Não tente controlar apt-get install com entrada padrão. Basta fornecer algumas opções apropriadas que "respondem" automaticamente às suas perguntas. Um rápido man apt-get mostra alguns candidatos:

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

Consulte o manual para obter detalhes.

Acho que esta é a maneira melhor e mais estável.

PS: No momento, estou pi *** o *** gksudo um pouco, então desculpe o discurso acima.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top