rag*_*ney 4 java apache-commons-exec
我正在尝试使用 Apache Commons Exec 来运行使用正则表达式的 git 命令。
当我形成CommandLine并打印出来时,它看起来像这样:
[git, --no-pager, grep, --line-number, --untracked, --extended-regexp, "^\s*public void\s+(testFindByAdAccount).*", --, *Test.java]
Run Code Online (Sandbox Code Playgroud)
但是,当我执行此操作时,git 没有返回任何结果,导致退出代码 1。
但是,当我手动运行此命令时,它会返回大量结果并成功。将参数更改--extended-regexp为字符串(如testFindByAdAccount通过 运行时)确实会产生结果Exec,因此我认为 Apache Commons 正在对 regexp 参数执行某些操作,使其无效。有什么想法吗?
编辑:添加可重现的示例
gradlew shadowJar为项目生成jar文件java -jar app/build/libs/app-all.jar$ java -jar app/build/libs/app-all.jar
HELLOOOOOO
WD::: null
[git, --no-pager, grep, --line-number, --untracked, --extended-regexp, "^\s*public void\s+(testAppHasAGreeting)\(\).*", --, *Test.java]
WD::: /Users/rgurney/Src/personal/min-example
Exception in thread "main" java.lang.RuntimeException: org.apache.commons.exec.ExecuteException: Process exited with an error: 1 (Exit value: 1)
at min.example.App.lambda$runCommand$1(App.java:74)
at io.vavr.control.Try.getOrElseThrow(Try.java:748)
Run Code Online (Sandbox Code Playgroud)
$ git --no-pager grep --line-number --untracked --extended-regexp "^\s*public void\s+(testAppHasAGreeting)\(\).*" -- "*Test.java"
app/src/test/java/min/example/AppTest.java:11: public void testAppHasAGreeting() {
Run Code Online (Sandbox Code Playgroud)
当您提供的示例在我的 Windows 笔记本电脑上运行良好但在我的 Linux 桌面上失败时,我了解到这里发生了什么。
一旦我确定 git 版本不是罪魁祸首(在两台机器上测试了 2.17 和 2.39 之间的多个版本),我认为差异一定在于不同的 shell 处理引用的方式。具体来说,这里唯一存在任何潜在引用问题的参数是正则表达式 ( "^\s*public void\s+(testFindByAdAccount).*"),它由 . 添加到命令行commandLine.addArgument(regex);。
addArgument可能看起来无害,但在幕后,它允许 CommandLine 处理引用本身(即addArgument(String argument)调用addArgument(String argument, true)。由于您自己处理了引用,所以您不应该允许CommandLine处理引用,并且应该使用第二个显式调用它论证false。即:
public static List<String> grep(String regex, String filePattern, String wd) {
CommandLine commandLine = CommandLine.parse("git");
commandLine.addArgument("--no-pager");
commandLine.addArgument("grep");
commandLine.addArgument("--line-number");
commandLine.addArgument("--untracked");
commandLine.addArgument("--extended-regexp");
commandLine.addArgument(regex, false);
// Here -----------------------^
commandLine.addArgument("--");
commandLine.addArgument(filePattern);
System.out.println(commandLine);
return List.of(runCommand(commandLine, wd).split("\n"));
}
Run Code Online (Sandbox Code Playgroud)
这消除了引用处理逻辑,并确保相同的代码在 Windows 和 Linux 上都能顺利运行(至少是我测试过的)。