简体   繁体   English

如何从Java程序中异步运行Shell脚本

[英]how to run shell script asynchronously from within Java program

I want to run a shell script from within a Java program asynchronously-- ie after the java program starts execution of that shell script, it carries on with other operations-- and does some further work only when the shell script returns a response to it.. ie it does not explicitly stop and wait for the shell script's response. 我想从Java程序中异步运行Shell脚本-即在Java程序开始执行该Shell脚本之后,它会继续执行其他操作-并且仅当Shell脚本返回对其的响应时才做进一步的工作..即它不会显式停止并等待shell脚本的响应。

Is this possible/feasible? 这可能/可行吗? How do I implement such functionality? 如何实现这种功能?

Basically i will be monitoring multiple servers using a single server that will manage all those servers-- for this it will run shell scripts on each of those servers...since there are many servers, and in java its recommended that number of threads not exceed number of cpu cores... hence I need a solution to this problem, that is not dependent on threading (because of threading limitations)...so that I can simultaneously (or near-simultaneously) fire off many such shell scripts without waiting for one of those scripts responses' (as waiting would affect processing for other shell script commands)... another issue.. the shell commands need to be invoked either on local machine or on remote machines and response is needed from both types of shell script execution(viz local execution and remote execution)... 基本上,我将使用一个将管理所有这些服务器的服务器来监视多个服务器-为此,它将在每个服务器上运行Shell脚本...因为有许多服务器,因此在Java中建议不要使用线程数量超过cpu核心的数量...因此,我需要一个不依赖线程的解决方案(由于线程限制)...以便我可以同时(或几乎同时)触发许多此类shell脚本而无需等待这些脚本之一响应(因为等待会影响其他shell脚本命令的处理)...另一个问题.. shell命令需要在本地计算机或远程计算机上调用,并且两种类型的响应都需要响应Shell脚本执行(即本地执行和远程执行)...

did you try anything? 你有尝试过吗?

you can try something like: 您可以尝试类似:

ProcessBuilder builder = new ProcessBuilder("your command to launch script");
Process process = builder.start();

And it does NOT wait by default for the process to complete, so you can execute your code next. 默认情况下,它不会等待过程完成,因此您可以下一步执行代码。

And if you want to do some processing after the process is finished you can try: 而且,如果您想在处理完成后进行一些处理,可以尝试:

int exitVal = process.waitFor();

When you execute another process and want to obtain a result from it, you usually have to read the output of that process, as the process might block if its output buffer becomes full. 当您执行另一个进程并希望从中获取结果时,通常必须读取该进程的输出,因为如果其输出缓冲区已满,则该进程可能会阻塞。 The easiest way to achieve this is by having a single thread in your Java application which starts the script and then reads its output into some buffer. 最简单的方法是在Java应用程序中只有一个线程,该线程启动脚本,然后将其输出读取到某个缓冲区中。 Other threads of the Java application can do whatever they want to do, and if the process is done, the thread can signal others about that event and then terminate. Java应用程序的其他线程可以执行其想执行的任何操作,如果该过程完成,则该线程可以向其他人发出有关该事件的信号,然后终止。

I don't know where your recommendation to not use more threads than CPUs originates from, but I'd not hold with that in general. 我不知道您的建议不要使用比CPU多的线程,这是从何而来的,但总体而言,我不赞成这样做。 This is true for worker threads, where each active thread keeps one core busy, but in your case, most threads would be idle most of the time. 对于工作线程来说,这是正确的,在工作线程中,每个活动线程都保持一个内核繁忙,但是在您的情况下,大多数线程在大多数时间都处于空闲状态。 There is some OS level resource overhead associated even with idle threads, so if there are really really many processes, using a single thread to read from all the streams would be better, but a lot more complicated. 即使有空闲线程,也存在一些OS级别的资源开销,因此,如果确实有很多进程,使用单个线程读取所有流会更好,但要复杂得多。

You can use Runtime.exec or ProcessBuilder in a different thread than your application main thread to run your shell script asynchronously. 您可以在与应用程序主线程不同的线程中使用Runtime.exec或ProcessBuilder来异步运行Shell脚本。

This post shows how to use Runtime or ProcessBuilder. 这篇文章展示了如何使用Runtime或ProcessBuilder。 Read this post to learn java threads if you are not aware of it. 如果您不了解Java线程,请阅读这篇文章

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM