3

我在使用 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”谢谢。

4

1 回答 1

1

有几个问题。

首先gksudo(1)对它启动的命令的标准输入和标准输出做了一些肮脏的、非标准的技巧。它失败了太可怕了。一个很好的例子是这个命令行:

$ echo foo | gksudo -g cat

我希望在交付数据cat后立即有任何输出和终止。echo没有。两者都gksudocat永远闲逛。没有输出。

你的用例是

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

这也行不通。只要不解决这个问题,如果启动的程序需要任何用户输入,您就可以忘记进行任何远程控制。

第二:正如罗杰已经指出的那样,waitFor()等待命令的终止。如果没有任何用户输入和 gksudo 问题,这不会很快发生。

第三,在推waitFor低一点之后,出现了下一个障碍:您等待该过程的完整输出,直到并包括 EOF。这不会很快发生(见“第一”和“第二”)。

第四只有在进程已经死了两次之后(参见“第二”和“第三”),它可能会得到一些输入 - 你的Y(可能还需要额外的\n)。


除了解决这一系列问题,可能还有更好更简单的方法:不要尝试apt-get install使用标准输入进行控制。只需给它一些适当的选项,它会自动“回答”您的问题。快速man apt-get找到一些候选人:

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

有关详细信息,请参阅手册。

我认为这是更好,更稳定的方式。

PS:现在我很生气gksudo,所以请原谅上面的咆哮。

于 2011-12-07T00:02:35.367 回答