Frage

Ich habe Probleme bei der Interaktion mit einem Prozess mit getOutputStream.Hier ist mein 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();

Hier ist die Ausgabe:

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 führt einfach "gksudo apt-get install Firefox" aus

Ich weiß nicht, warum es abgebrochen wird und nehme meine Eingabe nicht mit "Y", danke.

War es hilfreich?

Lösung

Es gibt mehrere Probleme.

Zuerst : gksudo(1) führt einige schmutzige, nicht standardmäßige Tricks mit der Standardeingabe und Standardausgabe der Befehle aus, die es startet. Es scheitert schrecklich. Ein gutes Beispiel ist diese Befehlszeile:

$ echo foo | gksudo -g cat

Ich würde jede Ausgabe und die Beendigung des cats erwarten, sobald der echo die Daten geliefert hat. Nee. Sowohl gksudo als auch cat hängen für immer herum. Keine Ausgabe.

Ihr Anwendungsfall wäre

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

und das funktioniert auch nicht. Solange dies nicht gelöst ist, können Sie vergessen, eine Fernbedienung durchzuführen, wenn das gestartete Programm Benutzereingaben erfordert.

Second : Wie bereits von Roger erwähnt, wartet waitFor() auf die Beendigung des Befehls. Dies wird ohne Benutzereingaben und mit dem gksudo-Problem nicht in Kürze geschehen.

Dritter Nachdem Sie den waitFor ein wenig nach unten verschoben haben, gibt es den nächsten Blocker: Sie warten auf die vollständige Ausgabe des Prozesses bis einschließlich des EOF. Dies wird nicht so schnell geschehen (siehe "erste" und "zweite").

Viertens Erst wenn der Prozess bereits zweimal tot ist (siehe "Zweiter" und "Dritter"), wird möglicherweise eine Eingabe angezeigt - Ihr Y (für den möglicherweise auch ein zusätzlicher \n erforderlich ist).


Anstatt diese Reihe von Problemen zu lösen, gibt es möglicherweise einen besseren und viel einfacheren Weg: Versuchen Sie nicht, apt-get install mit Standardeingabe zu steuern. Geben Sie ihm einfach einige geeignete Optionen, die Ihre Fragen automatisch "beantworten". Ein schneller man apt-get zeigt einige Kandidaten:

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

Einzelheiten finden Sie im Handbuch.

Ich denke, dies ist der bessere und stabilere Weg.

PS: Im Moment bin ich ziemlich viel gksudo, also entschuldigen Sie die Beschimpfungen oben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top