Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法调试ProcessBuilder_Java - Fatal编程技术网

Java 无法调试ProcessBuilder

Java 无法调试ProcessBuilder,java,Java,我需要使用java.lang.ProcessBuilder使用“sudo”和“su”将不同的sh命令从java应用程序传递到linux 这些命令非常相似,但有些有效,有些无效。当我从日志中复制粘贴命令时,ALL命令起作用 在此之后: processBuilder = new ProcessBuilder("sudo", "su", "- USER66 -c", "'ssh remote.mycomp.org < " + workingDir + "/script_cluster.sh'")

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

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

在此之后:

processBuilder = new ProcessBuilder("sudo", "su", "- USER66 -c", "'ssh remote.mycomp.org < " + workingDir + "/script_cluster.sh'");
processBuilder = new ProcessBuilder("sudo", "su",  "- USER66 -c", "'scp remote.mycomp.org:" + clusterWorkingDir + "/" + filename + " " + workingDir + "/resultat/" + dir + "/'");
但是这个:

processBuilder = new ProcessBuilder("sudo", "su", "- USER66 -c", "'ssh remote.mycomp.org < " + workingDir + "/script_cluster.sh'");
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();
  }
logCommand(processBuilder);
私有void日志命令(ProcessBuilder ProcessBuilder){
if(logger.isDebugEnabled()){
debug(“Commande:{}”,commandAsString(processBuilder.command());
}
}
私有字符串命令字符串(列表命令){
StringBuilder结果=新建StringBuilder();
for(字符串cmdElement:command){
result.append(cmdElement).append(“”);
}
返回result.toString();
}

我错过了什么?我还可以做些什么来理解发生了什么?

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

new ProcessBuilder( "sudo", "su", "-", "USER66", "-c", "'ssh remote.mycomp.org < /script_cluster.sh'");
newprocessbuilder(“sudo”、“su”、“-”、“USER66”、“c”、“ssh remote.mycop.org
(将-c标志的值视为一个参数应该是正确的。)

解释

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

在运行时,Java将把参数编码为一个字节数组,然后将其传递给本机JVM方法,该方法将调用本机系统方法。例如
“su”、“-”、“USER66”、“-c”、“…”
将被解码为
su-USER66-c'…'
。各个参数之间用0字节分隔(我们在字符串中没有看到)。本机JVM方法通过用0字节分隔符拆分字符串来解码continues字符串。如果我们
“su-USER66”
作为一个参数,它将被错误地编码为本机系统方法的一个参数


从shell或bash调用命令时,参数也会被拆分为数组,然后再传递给underline本机系统方法。

好的,我找到了一种解决此问题的令人惊讶的方法:

诀窍不是拆分参数,而是使用“bash-c”重新组合参数:

processBuilder=newprocessbuilder(“bash”、“-c”、“sudo su-USER66-c'ssh remote.mycop.org<“+workingDir+”/script_cluster.sh”);

请注意,这是多么不直观,因为没有人会在shell中这样编写它,而且在具有适当嵌套转义的shell命令中转换它可能会变得非常困难。另外,如果将3条命令与空格连接起来,则不会形成有效的命令。

我认为此假设忽略了一个事实,即我的第二条命令与“-USER66-c”配合使用效果良好。