0

我有一个script.sh需要由 java servlet 和手动运行的 shell 脚本。它的内容是:

service avahi-daemon restart
instance=MyInstance
avahi-publish -s -d local $instance _temp._tcp 443 "model=Model1"  > /dev/null 2>&1 &
# update: publish other services.

更新:它无法删除尾随 &,因为它avahi-publish不会返回但一旦启动就会继续运行,我需要发布其他服务。

servlet 是:

public class DefaultServlet extends HttpServlet{

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) {
        try {
            Process process = Runtime.getRuntime().exec("bash script.sh");
            process.waitFor();
        }catch (Exception ex) {
            System.out.println(ex.getMessage());
            ex.printStackTrace();
        }
    }
}

问题是,如果在浏览器中访问 servlet,服务 MyInstance 将不会发布。但是附加sleep 0.1s到脚本文件可以解决它。

我的问题是, Runtime.exec() 中是否有任何魔法以及为什么sleep需要该指令?

4

2 回答 2

2
avahi-publish -s -d local $instance _temp._tcp 443 "model=Model1"  > /dev/null 2>&1 &

由于尾随&,此脚本将退出并在命令完成Process.waitFor()之前返回。avahi-publish

删除尾随&.

您还应该删除重定向,并使用 servlet 中的输出,并测试进程的退出状态。为了协助这一点,我将exec用于该avahi-publish过程。

于 2016-09-28T05:04:41.103 回答
-1

最后我发现 ProcessBuilder 对我有帮助。这是我的伪代码:

protected void service(HttpServletRequest request, HttpServletResponse response) {
    new HandlerThread("avahi-publish","-s","-d", "local","MyInstance", "_https._tcp",
     "443","model=abc")
    .start();
}

private static class HandlerThread extends Thread {
    Process process;

    HandlerThread(String... args) {
        ProcessBuilder processBuilder = new ProcessBuilder(args);
        process = processBuilder.start();
    }

    public void run() {
         StringBuilder stringBuilder = new StringBuilder();

        try {
            process.waitFor();
            readStream(process.getInputStream(),stringBuilder);
            readStream(process.getErrorStream(),stringBuilder);
        }catch( IOException|InterruptedException ioe){
            System.out.println(ioe.getMessage());
        }
        System.out.println(stringBuilder);
    }
    private static String readStream(InputStream inputStream, StringBuilder sb) throws IOException {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(inputStream));
            String line = null;
            while ((line = br.readLine()) != null) {
                sb.append(line);
                sb.append('\n');
            }
        } finally {
            if(br!=null) br.close();
        }
        return sb.toString();
    }
}
于 2016-11-01T08:33:29.887 回答