我谷歌并检查了SO是否有任何代码来查找任何其他进程的PID。有一个解决方案可以创建一个外壳脚本,其中包含命令“ps-eaf|grep my进程”,并从java执行该脚本。
但我想使用java ProcessBuilder或运行时方法执行。下面是我尝试过的代码,它不会将null作为输出。
import java.io.*;
public class TestShellCommand {
public static void main(String args[]) {
Process p = null;
String command = "ps -ef | grep myProcess";
try {
// p = new ProcessBuilder(command).start();
p = Runtime.getRuntime().exec(command);
BufferedReader br[] = new BufferedReader[2];
br[1] = new BufferedReader(new InputStreamReader(p.getErrorStream()));
br[0] = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
if(br[0].readLine() == null){
System.out.println("The input stream is null.");
}
while ((line = br[0].readLine()) != null) {
System.out.println(line);
}
try {
br[0].close();
} catch (Exception a) {
a.printStackTrace();
}
try {
br[1].close();
} catch (Exception a) {
a.printStackTrace();
}
} catch (Exception grrr) {
grrr.printStackTrace();
} finally {
try {
closeStreams(p);
p.destroy();
} catch (Exception r) {
r.printStackTrace();
}
}
}
static void closeStreams(Process p) throws IOException {
p.getInputStream().close();
p.getOutputStream().close();
p.getErrorStream().close();
}
}
该命令的输出为:
java TestShellCommand
The input stream is null.
{sdc@ip-172-31-32-49}[26] echo $?
0
请让我知道我的代码中是否有任何错误,因为当我从shell手动搜索时,我确实得到了如下预期输出:
ps -ef | grep myProcess
root 7433 1 0 10:33 ? 00:00:00 myProcess hello
sdc 19894 14130 0 11:24 pts/7 00:00:00 grep myProcess
[更新的代码-没有grep命令]
import java.io.*;
public class TestShellCommand {
public static void main(String args[]) {
Process p = null;
String [] command = {"ps", "-eaf"};
try {
p = Runtime.getRuntime().exec(command);
BufferedReader br[] = new BufferedReader[2];
br[1] = new BufferedReader(new InputStreamReader(p.getErrorStream()));
br[0] = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
if(br[0].readLine() == null){
System.out.println("The input stream is null.");
}
while ((line = br[0].readLine()) != null) {
System.out.println(line);
}
// Then code to find by process name by using string methods ...
try {
br[0].close();
} catch (Exception a) {
a.printStackTrace();
}
try {
br[1].close();
} catch (Exception a) {
a.printStackTrace();
}
} catch (Exception grrr) {
grrr.printStackTrace();
} finally {
try {
closeStreams(p);
p.destroy();
} catch (Exception r) {
r.printStackTrace();
}
}
}
static void closeStreams(Process p) throws IOException {
p.getInputStream().close();
p.getOutputStream().close();
p.getErrorStream().close();
}
}
我添加了正在工作的代码,当我传递命令为:
new String[]{/bin/sh',“-c”,“ps-eaf | grep”“myProcess”“| grep-v grep”}
-空响应
new String[]{ps',“-eaf”,“grep-m1 myProcess”,“awk-F''{print$2}'}
-空响应
提前感谢您提供的任何线索。
您的问题是,您试图在命令中使用管道,因此需要一个shell来执行它。可以使用以下命令:
p = new ProcessBuilder("/bin/sh", "-c", "ps -aux | grep myProcess").start();
您可以在这里阅读更多内容:使用Java ProcessBuilder执行管道命令
为了测试它,我在shell中启动了top
,并将其作为grep模式运行命令。以下是我得到的输出:
<edited> 139890 0.4 0.0 23640 4376 pts/0 S+ 16:05 0:00 top
<edited> 139945 0.0 0.0 20996 3448 ? S 16:06 0:00 /bin/bash -c ps -aux | grep top
<edited> 139947 0.0 0.0 20536 2776 ? S 16:06 0:00 grep top
根据您的评论,我建议您首先在shell中运行命令来查看输出,并检查它是否与Java程序中的输出相匹配。我想myProcess
只是一个占位符,供实际进程检查。
我注意到的一件事是,当从快照运行htop时,在htop之后使用上面的代码进行grep时,将返回类似于您的注释中的答案,但按top进行grep将包括实际的过程。我还使用gedit进行了检查,看起来grep with gedit返回的结果与您的情况类似,但仅使用edit
将返回实际的过程。不确定这件事出了什么问题。
正如@Slimo answer所指出的,您必须启动一个shell来执行shell命令(管道),并读取错误流以确定可能出现的错误。
在不使用waitFor()
的情况下启动子流程,或同时使用stdout和stderr可能会导致问题,请使用文件重定向或本例中的merge stderr-
String procname = "myProcess";
String[] cmd = new String[]{"bash","-c", "ps -eaf | grep "+procname+" | grep -v grep"}
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
Process process = pb.start();
process.getInputStream().transferTo(System.out);
int rc = process.waitFor();
if (rc != 0)
throw new RuntimeException("Failed rc="+rc+" cmd="+Arrays.toString(cmd));
在以后的JDK中,您不需要ProcessBuilder,您可以在由ProcessHandle
返回的数据结构中找到所有进程属性:
ProcessHandle.allProcesses()
.filter(ph -> ph.info().command().isPresent() && ph.info().command().get().contains(procname))
.forEach(ph -> System.out.println("PID: "+ph.pid()+" command: "+ph.info().command()))
问题内容: 我想使用Java程序将avi文件转换为3gp。 为此,我使用“ EM Total Video Converter命令行2.43”,其命令为 “ C:\ EM TVCC > TVCC -f E:\ TestVideo \ 01.avi -o E:\ OutputFiles \ target.3gp” 我在站点http://www.rgagnon.com/javadetails/java-
问题内容: 我正在尝试在Java中为Linux / unix os执行awk命令,但问题是当我执行命令时它没有显示任何错误它。但是执行后没有输出,执行它需要几分之一秒,我不知道问题请帮忙。 该代码是 谢谢您的帮助 问题答案: 使用Java正确启动命令行过程并不容易。我建议您使用commons- exec 而不是自己尝试。 现在,您在命令行中有两件事需要特殊处理: AWK脚本周围的单引号。当您将每个
问题内容: 我如何在Java URLConnection中实现以下curl命令 提前致谢 问题答案: 使用URLConnection的派生类(即HttpURLConnection),您可以轻松地做到这一点。 对于
问题内容: 我想问一下如何多次执行1条命令 例如此代码 我要运行500次,该怎么办? 谢谢 问候威廉姆斯 问题答案: 使用循环, 请阅读基本的Java教程。可以在这里找到一个
问题内容: 我正在尝试通过Java执行命令行参数。例如: 上面的命令打开命令行,但是不执行或。有任何想法吗?我正在运行Windows XP,JRE6。 (我已经对问题进行了更详细的修订。以下答案很有用,但不能回答我的问题。) 问题答案: 你发布的代码使用自己的命令启动三个不同的过程。要打开命令提示符然后运行命令,请尝试以下操作(请勿自己尝试):
问题内容: 我正在使用ProcessBuilder执行bash命令: 但我想做这样的事情: 如何将超级用户密码传递给bash? 不会解决这个问题,因为它是从Ubuntu 13.04开始删除的,我需要使用默认命令来执行此操作。 编辑 gksudo在最近的更新中回到了Ubuntu 13.04。 问题答案: 我想您可以使用它,但是我有点犹豫要发布它。所以我只想说: 使用此方法后果自负,不建议您使用,请勿