Golang中执行mvn命令时无法使用-pl(--projects)选项的问题
Golang中执行mvn命令时无法使用-pl(–projects)选项的问题 使用go执行命令时,我尝试运行类似’mvn -pl test:test compile’的命令。但是go exec返回错误"无法解析命令行选项:无法识别的选项:-pl test:test compile"。
需要注意的是,如果我在命令行中运行该命令,它可以完美工作。使用–projects选项时也遇到同样的问题。
下面是我为演示问题设置的简单项目。第一个命令是mvn --version,第二个是有问题的命令,当使用bash作为命令运行时,它可以无缝执行。
有人知道为什么我的第二个命令会返回错误吗?
Go代码:
package main
import (
"os/exec"
"fmt"
"strings"
"bytes"
)
func main() {
//Calling mvn using bash since without it, we have an syntax error when using -pl (--projects) options
cmd := exec.Command("mvn", "--version")
//cmd := exec.Command("mvn", "compile")
funcName(cmd)
cmd2 := exec.Command("mvn", "-pl test:test compile")
//cmd := exec.Command("mvn", "compile")
funcName(cmd2)
cmd3 := exec.Command("bash", "-c", "mvn -pl test:test compile")
funcName(cmd3)
}
func funcName(cmd *exec.Cmd) {
cmd.Dir = "test"
fmt.Println("--------------------------------------------------------------------------------------", )
fmt.Println("Executing:", "'"+strings.Join(cmd.Args, " ")+"'", "With working directory:", cmd.Dir)
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
outStr, errStr := string(stdout.Bytes()), string(stderr.Bytes())
fmt.Printf("Command fail with: %s", errStr)
if err != nil {
fmt.Printf("Command fail with: %s\n", err)
}
fmt.Printf("Execution log: %s", outStr)
fmt.Println("--------------------------------------------------------------------------------------", )
}
输出:
Executing: 'mvn --version' With working directory: test
Command fail with: Execution log: Apache Maven 3.5.3 (3383c37e1f9e9b3bc3df5050c29c8aff9f295297; 2018-02-24T14:49:05-05:00)
Maven home: /home/dprevost/mfxdev-snapshot/software/apache-maven-3.5.3
Java version: 1.8.0_92, vendor: Oracle Corporation
Java home: /home/dprevost/mfxdev-snapshot/software/jdk1.8.0_92/jre
Default locale: en_CA, platform encoding: UTF-8
OS name: "linux", version: "4.15.0-22-generic", arch: "amd64", family: "unix"
--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------
Executing: 'mvn -pl test:test compile' With working directory: test
Command fail with: Unable to parse command line options: Unrecognized option: -pl test:test compile
Command fail with: exit status 1
Execution log:
usage: mvn [options] [<goal(s)>] [<phase(s)>]
Options:
-am,--also-make If project list is specified, also
build projects required by the
list
-amd,--also-make-dependents If project list is specified, also
build projects that depend on
projects on the list
-B,--batch-mode Run in non-interactive (batch)
mode (disables output color)
-b,--builder <arg> The id of the build strategy to
use
-C,--strict-checksums Fail the build if checksums don't
match
-c,--lax-checksums Warn if checksums don't match
-cpu,--check-plugin-updates Ineffective, only kept for
backward compatibility
-D,--define <arg> Define a system property
-e,--errors Produce execution error messages
-emp,--encrypt-master-password <arg> Encrypt master security password
-ep,--encrypt-password <arg> Encrypt server password
-f,--file <arg> Force the use of an alternate POM
file (or directory with pom.xml)
-fae,--fail-at-end Only fail the build afterwards;
allow all non-impacted builds to
continue
-ff,--fail-fast Stop at first failure in
reactorized builds
-fn,--fail-never NEVER fail the build, regardless
of project result
-gs,--global-settings <arg> Alternate path for the global
settings file
-gt,--global-toolchains <arg> Alternate path for the global
toolchains file
-h,--help Display help information
-l,--log-file <arg> Log file where all build output
will go (disables output color)
-llr,--legacy-local-repository Use Maven 2 Legacy Local
Repository behaviour, ie no use of
_remote.repositories. Can also be
activated by using
-Dmaven.legacyLocalRepo=true
-N,--non-recursive Do not recurse into sub-projects
-npr,--no-plugin-registry Ineffective, only kept for
backward compatibility
-npu,--no-plugin-updates Ineffective, only kept for
backward compatibility
-nsu,--no-snapshot-updates Suppress SNAPSHOT updates
-o,--offline Work offline
-P,--activate-profiles <arg> Comma-delimited list of profiles
to activate
-pl,--projects <arg> Comma-delimited list of specified
reactor projects to build instead
of all projects. A project can be
specified by [groupId]:artifactId
or by its relative path
-q,--quiet Quiet output - only show errors
-rf,--resume-from <arg> Resume reactor from specified
project
-s,--settings <arg> Alternate path for the user
settings file
-t,--toolchains <arg> Alternate path for the user
toolchains file
-T,--threads <arg> Thread count, for instance 2.0C
where C is core multiplied
-U,--update-snapshots Forces a check for missing
releases and updated snapshots on
remote repositories
-up,--update-plugins Ineffective, only kept for
backward compatibility
-v,--version Display version information
-V,--show-version Display version information
WITHOUT stopping build
-X,--debug Produce execution debug output
--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------
Executing: 'bash -c mvn -pl test:test compile' With working directory: test
Command fail with: Execution log: [INFO] Scanning for projects...
[INFO]
[INFO] -----------------------------< test:test >------------------------------
[INFO] Building test 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ test ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ test ---
[INFO] Nothing to compile - all classes are up to date
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.560 s
[INFO] Finished at: 2018-06-12T11:16:10-04:00
[INFO] ------------------------------------------------------------------------
--------------------------------------------------------------------------------------
更多关于Golang中执行mvn命令时无法使用-pl(--projects)选项的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html
谢谢,现在可以正常工作了。顺便问一下,你知道有没有办法在shell中准确输出go正在运行的命令吗?
更多关于Golang中执行mvn命令时无法使用-pl(--projects)选项的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这正是关键所在……没有任何内容是在shell中运行的。
在Go中需要使用的形式,是shell在执行其实现语言的类似调用之前会解析成的形式。
问题在于Go的exec.Command函数将每个参数作为单独的命令行参数传递给目标程序。当您使用exec.Command("mvn", "-pl test:test compile")时,Go实际上传递的是单个参数"-pl test:test compile",而Maven期望的是三个独立的参数:-pl、test:test和compile。
正确的做法是将命令参数拆分为独立的字符串:
package main
import (
"os/exec"
"fmt"
"strings"
"bytes"
)
func main() {
// 正确的方式:将每个参数作为独立的字符串
cmd := exec.Command("mvn", "-pl", "test:test", "compile")
funcName(cmd)
}
func funcName(cmd *exec.Cmd) {
cmd.Dir = "test"
fmt.Println("--------------------------------------------------------------------------------------")
fmt.Println("Executing:", "'"+strings.Join(cmd.Args, " ")+"'", "With working directory:", cmd.Dir)
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
outStr, errStr := string(stdout.Bytes()), string(stderr.Bytes())
if err != nil {
fmt.Printf("Command fail with: %s\n", err)
fmt.Printf("Stderr: %s", errStr)
}
fmt.Printf("Execution log: %s", outStr)
fmt.Println("--------------------------------------------------------------------------------------")
}
或者,如果您需要动态构建参数,可以使用切片:
args := []string{"-pl", "test:test", "compile"}
cmd := exec.Command("mvn", args...)
对于更复杂的命令行场景,比如包含管道或重定向,使用bash -c仍然是有效的解决方案:
cmd := exec.Command("bash", "-c", "mvn -pl test:test compile | grep SUCCESS")
关键点是:Go的exec.Command期望每个命令行参数都是独立的字符串元素,而不是将整个命令行作为一个字符串。


