ProcessBuilder getOutputStream и взаимодействие с процессами - PullRequest
3 голосов
/ 07 декабря 2011

У меня проблемы с взаимодействием с процессом с использованием getOutputStream.Вот мой код:

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

Вот вывод:

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 просто запускает "gksudo apt-get install firefox"

Я нене знаю, почему он прерывает и не принимает мой ввод "Y", спасибо.

1 Ответ

1 голос
/ 07 декабря 2011

Есть несколько проблем.

Первый : gksudo(1) выполняет некоторые грязные, нестандартные приемы со стандартным вводом и стандартным выводом команд, которые он запускает. Это терпит неудачу ужасно. Хорошим примером является эта командная строка:

$ echo foo | gksudo -g cat

Я ожидал бы любой вывод и завершение cat, как только echo доставит данные. Нету. И gksudo, и cat вечно торчат. Нет вывода.

Ваш вариант использования будет

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

и это тоже не сработает. Пока это не решено, вы можете забыть сделать любое дистанционное управление, если запущенная программа требует какого-либо пользовательского ввода.

Секунда : Как уже указывал Роджер, waitFor() ожидает завершения команды. Это не произойдет в ближайшее время без участия пользователя и проблемы gksudo.

Третий После небольшого сброса waitFor появляется следующий блокировщик: Вы ожидаете выхода complete процесса вплоть до EOF. Это не произойдет в ближайшее время (см. «Первое» и «второе»).

Четвертый Только после того, как процесс уже дважды мертв (см. «Второй» и «третий»), он может получить некоторый ввод - ваш Y (который также может потребовать дополнительный \n).


Вместо решения этой группы проблем может быть лучший и более простой способ: не пытайтесь управлять apt-get install стандартным вводом. Просто дайте ему несколько подходящих опций, которые автоматически «отвечают» на ваши вопросы. Быстрый man apt-get вызывает некоторых кандидатов:

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

Подробнее см. В руководстве.

Я думаю, что это лучший и более стабильный способ.

PS: Прямо сейчас я немного пи *** о *** gksudo, так что извините рассудок выше.

...