gpt4 book ai didi

java - 无法调试 ProcessBuilder

转载 作者:行者123 更新时间:2023-12-02 00:23:51 27 4
gpt4 key购买 nike

我需要使用 java.lang.ProcessBuilder 将使用“sudo”和“su”的不同 sh 命令从我的 java 应用程序传递到 Linux。

这些命令非常相似,但有些有效,有些无效。当我从日志中复制粘贴命令时,所有命令都有效。

在这之后:

processBuilder = new ProcessBuilder("sudo", "su", "- USER66 -c", "'ssh remote.mycomp.org < " + workingDir + "/script_cluster.sh'");

我有:

su : option invalide -- ' '
Usage: (...)

但是这个:

processBuilder = new ProcessBuilder("sudo", "su",  "- USER66 -c", "'scp remote.mycomp.org:" + clusterWorkingDir + "/" + filename + " " + workingDir + "/resultat/" + dir + "/'");

工作完美。

就像我之前说的,如果我从日志中复制第一个命令,它工作时没有任何警告。

记录代码:

  logCommand(processBuilder);

private void logCommand(ProcessBuilder processBuilder) {
if (logger.isDebugEnabled()) {
logger.debug("Commande : {}", commandAsString(processBuilder.command()));
}
}

private String commandAsString(List<String> command) {
StringBuilder result = new StringBuilder();
for (String cmdElement : command) {
result.append(cmdElement).append(" ");
}
return result.toString();
}

我在这里缺少什么?我还能做些什么来了解正在发生的事情?

最佳答案

ProcessBuilder 构造函数要求每个参数都有一个单独的字符串。在您的代码中,多个参数组合在一个字符串中。试试这个:

new ProcessBuilder( "sudo", "su", "-", "USER66", "-c", "'ssh remote.mycomp.org < /script_cluster.sh'");

(将 -c 标志的值视为一个参数应该是正确的。)

说明

大多数创建新进程的 native 系统方法都要求每个参数作为数组的单独元素(例如,查看 execve 文档)。

在运行时,Java 会将参数编码为一个连续字节数组,然后将其传递给 native JVM 方法,该方法将调用 native 系统方法。例如 "su", "-", "USER66", "-c", "'...'" 将被解码为 su-USER66-c'...' 。各个参数由 0 字节分隔(我们在字符串中看不到)。 native JVM 方法通过用 0 字节分隔符分割字符串来解码连续字符串。如果我们将“su - USER66”作为一个参数,它将被错误地编码为 native 系统方法的一个参数。

当您从 shell 或 bash 调用命令时,参数也会被拆分为一个数组,然后再传递给下划线 native 系统方法。

关于java - 无法调试 ProcessBuilder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58066630/

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