ProcessBuilder getOutputStream et interagir avec les processus
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.
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.