2011-12-06 248 views
3

我无法与使用getOutputStream的进程进行交互。这里是我的代码:ProcessBuilder 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的安装Firefox”

我不知道为什么它被中止并没有把我的输入“Y”谢谢。

+0

我真的不认为你应该尽快关闭流,只要你发送了“Y”。 –

+0

我可以将其移至最后,但不会改变行为。事情是在它到达我的outputStream之前它正在中止。 – Eric

+1

第一次阅读时漏掉了一些东西。在获取输入和输出流之前,先从p.waitFor()开始。根据javadoc,这个等待直到过程死亡。这是你想要的吗?死后发送'Y'似乎毫无意义。 –

回答

1

有几个问题。

第一个gksudo(1)做了一些肮脏,非标准的技巧与它启动的命令的标准输入和标准输出。它失败了。一个很好的例子是这样的命令行:

$ echo foo | gksudo -g cat 

我希望任何输出和cat的尽快echo已交付的数据终端。不。 gksudocat永远都在。没有输出。

你的用例将

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

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

第二个:正如Roger 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:现在我很蠢,所以原谅了上面的咆哮。

+0

我同意你在gksudo,所以我喜欢这个咆哮。非常感谢你的帮助 – Eric