gpt4 book ai didi

java - 通过 Runtime.exec() 执行管道 ps unix 命令时出现问题

转载 作者:行者123 更新时间:2023-12-02 02:22:39 25 4
gpt4 key购买 nike

问题:

通过 Runtime.exec(...) 执行以下命令时,在查找匹配的引号字符时会失败并出现意外的 EOF。

一个奇怪的地方是错误消息有一个严重字符,后跟两个单引号。

但是,当我通过putty执行在日志中打印出来的命令时,它工作得很好。

命令:

bin/sh -c 'ps -eo uname,pid,ppid,nlwp,pcpu,pmem,psr,start_time,tty,time,args | fgrep IAAPC | fgrep /f1/f2/a00-a/f3/server/server_1/env_1/javadriver | fgrep -v fgrep'

结果错误:

-eo: -c: line 0: unexpected EOF while looking for matching `''
-eo: -c: line 1: syntax error: unexpected end of file

Java 代码(Java 1.6 ...不要判断):

    String driverHome = trimToEmpty(System.getProperty("batchdriver.home"));
String cmd = "/bin/sh -c 'ps -eo uname,pid,ppid,nlwp,pcpu,pmem,psr,start_time,tty,time,args | fgrep "+jobName+" | fgrep "+driverHome+" | fgrep -v fgrep'";
String out = null, err = null;
Process proc = null;
try {
proc = Runtime.getRuntime().exec(cmd);

out = fullyRead(proc.getInputStream());
err = fullyRead(proc.getErrorStream());

int exitVal = proc.waitFor();

if(logger.isDebugEnabled()) {
logger.debug("Process Information: "+out);
}
if (isNotEmpty(err)) {
logger.error(failedCommandMessage(cmd, out, err));
this.processId = null;
this.processDesc = PROCESS_NOT_FOUND;
return;
}

String[] processes = StringUtils.split(out, "\r?\n");
if (processes == null || processes.length == 0) {
this.processDesc = PROCESS_NOT_FOUND;
}
else if (processes.length == 1) {
String[] processInfo = processes[0].split("\\s+");
this.processId = processInfo[1];
if (!isNumeric(this.processId)) {
this.processId = null;
}
this.processDesc = out;
}
else {
this.processDesc = out;
}
if (logger.isDebugEnabled()) {
logger.debug("Call to the OS completed with exit value: " + exitVal);
}
} catch (Exception e) {
try {out = fullyRead(proc.getInputStream());} catch (Exception e1) {}
try {err = fullyRead(proc.getErrorStream());} catch (Exception e1) {}
this.processId = null;
this.processDesc = PROCESS_NOT_FOUND;
logger.error(failedCommandMessage(cmd, out, err), e);
}

最佳答案

相关但不完全是骗人的:Pass a string with multiple contiguous spaces as a parameter to a jar file using Windows command prompt called from a java program

The Runtime.exec methods that take a String将其分解为 token at whitespace only所以这实际上使用以下参数运行程序 /bin/sh (一个 shell):

 -c
'ps
-eo
uname,pid,ppid,nlwp,pcpu,pmem,psr,start_time,tty,time,args
|
fgrep
...

shell 像这样解释这些参数:

 -c 'ps -- the script to run consists of the apostrophe character, p, s (and nothing more)
-eo -- the name of the command being run is -eo
uname,pid,.... -- the first argument to the script is this
| -- the second argument to the script is this
fgrep -- the third argument to the script is this
...
-- but the script ignores the arguments and doesn't use them

这样你就得到了

-eo: -c: unexpected EOF while looking for matching `''
# the script named -eo, with the option -c having value 'ps,
# tried to find a closing ' to match the opening ' and it's not there

这个 shell 显然是 (GNU) bash;许多 GNU 程序将数据字符串放入错误消息中,并用反引号和撇号将其括起来,因为这些是几十年前流行的 ASCII 解释中的匹配引号。

而是使用 the String[] overload of exec为 shell 提供当您的上述命令行由 shell 解析时获得的两个参数,而不是由 StringTokenizer 解析:

 String[] cmdary = {"/bin/sh", "-c", "ps -eo stuff | fgrep this | fgrep that | fgrep -v fgrep"};
... Runtime.getRuntime().exec(cmdary);

但是,您可以只运行 ps 并将输入流读取为行,然后使用 String.contains 或类似工具在 Java 中测试它们,而不是运行三个 fgrep。此外,您要求 ps 的大多数列永远不会用于您的匹配结果,因此这只是浪费精力和困惑。

关于java - 通过 Runtime.exec() 执行管道 ps unix 命令时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48286438/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com