Question

J'ai du mal à interagir avec un processus en utilisant GetOutputStream. Voici mon code:

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

Voici la sortie:

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

Ce.sh exécute simplement "Gksudo apt-get install firefox"

Je ne sais pas pourquoi il abandonne et ne prend pas ma contribution "y" merci.

Était-ce utile?

La solution

Il y a plusieurs problèmes.

Première: gksudo(1) fait des astuces sales et non standard avec l'entrée standard et la sortie standard des commandes qu'il démarre. Ça échoue horrible. Un bon exemple est cette ligne de commande:

$ echo foo | gksudo -g cat

Je m'attendrais à toute sortie et à la résiliation du cat aussi tôt que le echo a livré les données. Non. Tous les deux gksudo et cat traîner pour toujours. Aucune sortie.

Votre utilisation serait

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

Et cela ne fonctionnera pas non plus. Tant que cela n'est pas résolu, vous pouvez oublier de faire une télécommande si le programme démarré nécessite une entrée utilisateur.

Deuxième: Comme déjà souligné par Roger waitFor() attend la résiliation de la commande. Cela ne se produira pas de sitôt sans aucune entrée utilisateur et avec le problème GKSUDO.

Troisième Après avoir poussé waitFor un peu il y a le prochain bloqueur: vous attendez le Achevée Sortie du processus jusqu'à et y compris l'EOF. Cela ne se produira pas de sitôt (voir "Premier" et "Second").

Quatrième Ce n'est qu'après que le processus soit déjà mort deux fois (voir "deuxième" et "troisième"), il pourrait obtenir des commentaires - votre Y (qui pourrait également nécessiter un \n).


Au lieu de résoudre ce tas de problèmes, il pourrait y avoir un moyen meilleur et beaucoup plus facile: n'essayez pas de contrôler apt-get install avec entrée standard. Donnez-lui simplement quelques options appropriées qui "répondent automatiquement" à vos questions. Un rapide man apt-get avance certains candidats:

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

Voir le manuel pour plus de détails.

Je pense que c'est la manière meilleure et plus stable.

PS: en ce moment je suis pi *** o *** gksudo Un peu, alors excusez la diatribe au-dessus.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top