这就是我正在做的事情:
import org.apache.commons.exec.*;
String cmd = "/bin/sh -c \"echo test\"";
new DefaultExecutor().execute(CommandLine.parse(cmd));
这是输出:
/bin/sh: echo test: command not found
我做错了什么?
答案 0 :(得分:8)
根据the FAQ“建议使用CommandLine.addArgument()
代替CommandLine.parse()
”。
所以试试
CommandLine commandLine = new CommandLine("/bin/sh");
commandLine.addArgument("-c");
commandLine.addArgument("echo test", false); // false is important to prevent commons-exec from acting stupid
executor.execute(commandLine);
答案 1 :(得分:3)
这个对我有用: -
CommandLine command = new CommandLine("/bin/sh");
command.addArguments(new String[] {
"-c",
"echo 'test'"
},false);
new DefaultExecutor().execute(command);
答案 2 :(得分:0)
我可以从shell命令行重现您的问题:
# /bin/sh -c '"echo test"'
# /bin/sh: echo test: command not found
我会说你应该试着不引用这个命令。
答案 3 :(得分:0)
var obj = JsonConvert.DeserializeObject<Dictionary<int, AClass>>(JsonConvert);
public class AClass
{
public string key { set; get; }
public string key2 { set; get; }
}
答案 4 :(得分:0)
该命令不起作用,因为commons-exec对所有参数进行不必要的引用,这些参数有空格或引用。
这种不必要的参数引用由每个参数的handleQuoting
标志控制。如果使用构造函数和CommandLine
方法创建addArgument
对象,则可以将此标志设置为false
。
像这样:
CommandLine commandLine = new CommandLine("/bin/sh");
commandLine.addArgument("-c");
commandLine.addArgument("echo test", false);
(重要的部分是false
作为addArgument
方法的第二个参数)
它有效!但是......手动构造命令行而不是在某个配置文件中定义它是不合理的。
CommandLine.parse
始终将handleQuoting
标志设置为true!谁知道为什么......
我使用反射来编写这个小帮助方法来修复使用CommandLine
创建的“坏”CommandLine.parse
对象。
public static CommandLine fixCommandLine(CommandLine badCommandLine) {
try {
CommandLine fixedCommandLine = new CommandLine(badCommandLine.getExecutable());
fixedCommandLine.setSubstitutionMap(badCommandLine.getSubstitutionMap());
Vector<?> arguments = (Vector<?>) FieldUtils.readField(badCommandLine, "arguments", true);
arguments.stream()
.map(badArgument -> {
try {
return (String) FieldUtils.readField(badArgument, "value", true);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
})
.forEach(goodArgument -> fixedCommandLine.addArgument(goodArgument, false));
return fixedCommandLine;
} catch (Exception e) {
logger.error("Cannot fix bad command line", e);
return badCommandLine;
}
}
它只是克隆给定的CommandLine
,将每个参数的handleQuoting
标志设置为false
。
方法FieldUtils.readField
来自commons-lang3库,但如果需要,可以使用纯反射。
它允许解析命令行并仍然成功执行它。
String cmd = "/bin/sh -c 'echo test'";
new DefaultExecutor().execute(fixCommandLine(CommandLine.parse(cmd)));