unix Java -如何检查Linux上是否正在运行另一个(非Java)进程

nwsw7zdq  于 2022-11-04  发布在  Unix
关注(0)|答案(5)|浏览(267)

我有一些奇怪的问题。
我们正在使用Xvfb虚拟桌面管理器,并希望在继续之前确保它正在运行。使用纯shell,我可以很容易地做到这一点:

ps -ef | grep Xvfb | grep -v grep

这正是我所需要的,一行包含了关于Xvfb进程的信息。接下来,我想把它合并到我的Java程序中,解析结果并存储正在运行的Xvfb进程的PID。因此,我尝试这样做:

String line;
    try {
      Process p = Runtime.getRuntime().exec("ps -ef | grep Xvfb | grep -v grep");
      BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
      while ((line = input.readLine()) != null)
      {
        System.out.println(line);
      }
    } catch (Exception err) {
      System.out.println(err);
    }

奇怪的是,如果我使用“ps -ef”,当我运行应用程序时,我会得到一个巨大的进程列表转储到我的控制台。|grep来缩小返回的进程列表,我得到零个结果。input.readLine()每次都得到null。
我也试过:

ps -ef | grep Xvfb | grep -v grep | awk {'print $2'}

只是为了获取进程ID。还有,运气不好。
有没有其他人经历过或者知道我做错了什么?

hs1rzwqc

hs1rzwqc1#

你在尝试使用“|“,这是shell特有的管道函数,因此不能在java进程中执行此操作。您可以尝试使用pidof Xvfb获取进程ID。

ztyzrc3y

ztyzrc3y2#

也许Runtime.getRuntime().exec()试图执行程序,因为它是在参数中。也就是说,它运行程序ps与参数-ef|grep等。所以,程序失败,因为它不知道发生了什么。
如果需要运行管道命令,则应显式调用shell:

Runtime.getRuntime().exec(new String[] {"sh", "-c", "ps -ef | grep Xvfb | grep -v grep"});
deyfvvtc

deyfvvtc3#

当你直接执行你的命令字符串时,你不会得到一个shell,它是处理管道的shell。|grep Xvfb| grep -v grep"”

dsekswqp

dsekswqp4#

有很多方法可以实现这一点。你可以使用java.lang.ProcessBuilder和“pgrep”来获取进程ID(PID),如下所示:pgrep -fl java | awk {'print $1'}。或者,如果您是在Linux下执行,则可以查询/proc目录。
我知道,这看起来很可怕,不可移植,甚至实现得很差,我同意。但是因为Java实际上是在VM中运行的,出于一些荒谬的原因,我在JDK工作了15年之后,真的搞不懂,这就是为什么不可能看到JVM空间之外的东西,如果你仔细想想,这真的很荒谬。你可以做其他任何事情,甚至是fork和join子进程(* 当世界不知道threadspthreads时,这是一种可怕的多任务处理方式,真是见鬼!Java到底怎么了?!*:)。
我知道这会给予很大的讨论,但无论如何,有一个非常好的API,我已经在我的项目中使用过了,它足够稳定(它是OSS,所以在真正信任该API之前,您仍然需要对您使用的每个版本进行压力测试):https://github.com/jezhumble/javasysmon
JavaDoc:http://jezhumble.github.io/javasysmon/,搜索类com.jezhumble.javasysmon.OsProcess,她会做到这一点。希望它能帮上忙,祝你好运。

xvw2m8pv

xvw2m8pv5#

不确定这是否有帮助,但我只是必须检查我的应用程序的另一个示例是否在Linux中运行,所以我实现了这一点,它可以返回另一个示例的计数或PID(这样我就可以放在前面并停止加载新示例)。

public long checkIsAlreadyRunning(){
    //Check if app is already running
     long lngCountOfInstances = 0; //Use this to hold how many already running
     String strProcessName = "AG2_GetData";
     //If it is required to also capture app running from within NetBeans, remove the .jar
     so("ps -ef|grep " + strProcessName);
     try{
         long lngPid = ProcessHandle.current().pid();//PID of this instance of the application
         long lngPidOfRunning = 0; //Holder for PID of already running instance
         System.out.println(lngPid+""); //Only for verification

         Runtime rt = Runtime.getRuntime();
         String[] cmd = {"/bin/sh", "-c", "ps -ef|grep " + strProcessName };
         Process proc = rt.exec(cmd);

         delay_ms(2);//found I needed small delay to ensure buffer was ready

         BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));

         String strLineIn;
         StringBuilder strOutput = new StringBuilder();
         String strProcessId = "";
         while ((strLineIn = reader.readLine()) != null) {                   
            if(!strLineIn.contains("grep") && !strLineIn.contains(String.valueOf(lngPid))) {//ignore is PID is current, or line contais grep 
                strOutput.append(strLineIn + "\r\n");//Only here for debuging
                lngCountOfInstances++;
            }
         }
         reader.close(); //always close the reader
         String strReturn = removeDuplicates(strOutput.toString()," "); // remove duplicate spaces frm reteun
         String[] strArray = strReturn.split(" ");
         if(strArray.length>2){lngPidOfRunning = isLong(strArray[1]);}//Aray index 1 will be PID, isLong checks if valid long and if yes, retunrs long, esle 0;
         System.out.println(lngPidOfRunning + " --> " + strReturn); //Only here for debuging
     }
     catch(Exception ex){
         ex.printStackTrace();
         err(ex.getMessage(), ex); //remove this, I use function to log messages and stacktraces to file
     }
     //return lngPidOfrunning; //Use this is you would like to use the PID to bring running instance to front
     return lngCountOfInstances; //use this if you just want to get count of running instances
}

相关问题