如何使用java Runtime执行交互式shell脚本?

时间:2012-03-29 14:29:33

标签: java runtime.exec

我想知道有没有办法执行以下shell脚本,它等待使用java的Runtime类的用户输入?

#!/bin/bash

echo "Please enter your name:"
read name
echo "Welcome $name"

我正在使用以下java代码来执行此任务,但它只显示空白控制台。

public class TestShellScript {
public static void main(String[] args) {

        File wd = new File("/mnt/client/");
           System.out.println("Working Directory: " +wd);
           Process proc = null;

           try {
               proc = Runtime.getRuntime().exec("sudo ./test.sh", null, wd);

           } catch (Exception e) {
             e.printStackTrace();
             }


}

}

当我执行上面的程序时,我相信它将执行一个shell脚本,而shell脚本将等待用户输入,但它只打印当前目录然后退出。有没有办法做到这一点,或者在java中根本不可能?

提前致谢

4 个答案:

答案 0 :(得分:1)

它打印当前目录和退出的原因是因为您的Java应用程序退出。您需要向创建的进程的输入和错误流添加(线程)侦听器,并且您可能希望将printStream添加到进程的输出流

示例:



            proc = Runtime.getRuntime().exec(cmds);
            PrintStream pw = new PrintStream(proc.getOutputStream());
            FetcherListener fl = new FetcherListener() {

                @Override
                public void fetchedMore(byte[] buf, int start, int end) {
                    textOut.println(new String(buf, start, end - start));
                }

                @Override
                public void fetchedAll(byte[] buf) {
                }           
            };
            IOUtils.loadDataASync(proc.getInputStream(), fl);
            IOUtils.loadDataASync(proc.getErrorStream(), fl);
            String home = System.getProperty("user.home");
            //System.out.println("home: " + home);
            String profile = IOUtils.loadTextFile(new File(home + "/.profile"));
            pw.println(profile);
            pw.flush();

要运行它,您需要下载我的sourceforge项目:http://tus.sourceforge.net/但希望代码片段足够有用,您可以适应J2SE以及您正在使用的任何其他内容。

答案 1 :(得分:1)

如果您使用Java ProcessBuilder,您应该能够获得您创建的Process的输入,错误和输出流。

这些流可用于获取流程中的信息(如输入提示),但也可以编写它们以直接将信息输入流程。例如:

InputStream stdout = process.getInputStream ();
BufferedReader reader = new BufferedReader (new InputStreamReader(stdout));

String line;
while(true){
    line = reader.readLine();
    //...

这将直接从过程中获得输出。我自己没有这样做,但我很确定process.getOutputStream()为您提供了可以直接写入的内容,以便将输入发送给流程。

答案 2 :(得分:1)

sudo运行交互式程序(例如Runtime.exec)的问题在于它将stdin和stdout附加到管道而不是所需的控制台设备。您可以通过redirecting the input and output to /dev/tty使其正常工作。

您可以使用新的ProcessBuilder类实现相同的行为,使用ProcessBuilder.Redirect.INHERIT设置重定向。

答案 3 :(得分:0)

请注意,您可以从Java向脚本发送输入。但是,如果您要从Java执行外部脚本,我强烈建议您查看Commons Exec:

Commons Exec homepage

Commons Exec API