【问题标题】:How to get Maven project version to the bash command line如何将 Maven 项目版本获​​取到 bash 命令行
【发布时间】:2011-04-02 11:56:37
【问题描述】:

之前我在how to change Maven project vesion from command line 上发布了一个问题,这导致我遇到了一个新问题。

以前我能够获得版本号,因为版本被存储为一个易于从命令行 (bash) 进行 grep 和解析的属性。现在 pom.xml <version> 元素用于此,它不再是唯一的,因为所有依赖项,也许其他一些依赖项也使用它。我认为没有办法使用 bash 脚本获取当前版本号没有用于解析 XML 的外部工具或一些非常上下文感知的 sed 命令。

我认为最干净的解决方案是让 Maven 分发此版本信息。我正在考虑编写一个自定义 maven 插件来检索不同的属性,但我想我会先在这里问。

那么,有没有什么简单的方法可以将${project.version} 的值传到命令行呢?

解决方案

我不得不手动 cd 到目录,但这很容易做到。在我的 bash 脚本中,我有:

version=`cd $project_loc && mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | sed -n -e '/^\[.*\]/ !{ /^[0-9]/ { p; q } }'`

这为我提供了当前版本,然后我可以升级。 Grepping 可能更简单,但我认为我希望尽可能健壮,所以我对以数字开头的第一行感到满意,并尝试将其作为版本号处理。

# Advances the last number of the given version string by one.
function advance_version () {
    local v=$1
    # Get the last number. First remove any suffixes (such as '-SNAPSHOT').
    local cleaned=`echo $v | sed -e 's/[^0-9][^0-9]*$//'`
    local last_num=`echo $cleaned | sed -e 's/[0-9]*\.//g'`
    local next_num=$(($last_num+1))
    # Finally replace the last number in version string with the new one.
    echo $v | sed -e "s/[0-9][0-9]*\([^0-9]*\)$/$next_num/"
}

我通过简单地调用来使用它:

new_version=$(advance_version $version)

【问题讨论】:

  • 解决方案似乎缺少一个 ' 来完成 sed 表达式。
  • 哪个 sed exp?我似乎没有注意到。
  • 将其设为 mvn -o 以加快执行速度
  • 你可以用简单的grep -e '^[[:digit:]]'替换那个复杂的sed表达式
  • 如果您按照@NathanBubna 的建议使用 -o ,那么这将使 maven 处于“离线”模式。如果您还没有下载 maven 帮助插件和相关 jar,那么构建将失败。被烧了一点,希望它可以帮助别人。

标签: bash command-line maven-2


【解决方案1】:

Maven Help Plugin 不知何故已经为此提出了一些建议:

  • help:evaluate 以交互模式计算用户给出的 Maven 表达式。

这是在命令行中调用它以获取 ${project.version} 的方法:

mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate \
    -Dexpression=project.version

【讨论】:

  • 好的,谢谢。我认为这是我最接近清洁解决方案的方法。有什么想法可以抑制 Maven 输出并过滤掉那些 [INFO] 消息吗?我没有找到maven的开关。否则我将添加一些命令行脚本来解析版本号。
  • 我正在使用mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version|grep -Ev '(^\[|Download\w+:)'删除所有日志记录(信息、警告等)和“下载”消息
  • 不会期望 maven 有更详细的内容
  • 这是我喜欢的一种方法:printf 'VERSION=${project.version}\n0\n' | mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate | grep '^VERSION'
  • @montoyaed 发布了best answer,即mvn help:evaluate -Dexpression=project.version -q -DforceStdout。要在 Bash 中的变量中捕获它,请使用 version=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
【解决方案2】:
mvn help:evaluate -Dexpression=project.version | sed -e 1h -e '2,3{H;g}' -e '/\[INFO\] BUILD SUCCESS/ q' -e '1,2d' -e '{N;D}' | sed -e '1q'

我只是添加了一个小的 sed 过滤器改进,我最近实现了从 maven 输出中提取 project.version

【讨论】:

  • Maven 命令适用于我,但 sed 不适用 sed: 1: "2,3{H;g} ": extra characters at the end of g command
【解决方案3】:
mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\['

【讨论】:

  • 制作 mvn -o 以加快执行速度
  • 查看我的答案(quickshiftin),下方也过滤了“已下载:”行。
  • 如果您按照@NathanBubna 的建议使用 -o ,那么这将使 maven 处于“离线”模式。如果您还没有下载 maven 帮助插件和依赖 jar,那么构建将失败。被烧了一点,希望它可以帮助别人。
  • 您可能还想添加2> /dev/null,否则您可以获得Picked up _JAVA_OPTIONS:
  • 在 Windows 上,将命令末尾替换为 | findstr /v "["
【解决方案4】:

我注意到输出中出现了一些虚假的Downloaded: 行,这些行破坏了我的原始任务。这是我选择的过滤器;希望有帮助!

version=$(mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | egrep -v '^\[|Downloading:' | tr -d ' \n')

编辑

不是 100% 确定原因,但是当通过 Jenkins 中的构建后脚本运行它时,输出为 [INFO]version,例如[INFO]0.3.2.

我将输出转储到一个文件中,并直接从 BASH 中通过我的第一个过滤器运行它,它工作正常......所以再次不确定 Jenkins 领域发生了什么。

为了在 Jenkins 中实现 100%,我添加了一个后续 sed 过滤器;这是我最新的

version=$(mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | egrep -v '^\[|Downloading:' | tr -d ' \n' | sed -E 's/\[.*\]//g')

编辑

最后一点在这里.. 我发现tr 仍然是 导致类似/r/n0.3.2 的东西(同样仅在通过 Jenkins 运行时)。切换到awk,问题就消失了!我的最终工作结果

mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version \
| egrep -v '^\[|Downloading:' | sed 's/[^0-9\.]//g' | awk 1 ORS=''

【讨论】:

    【解决方案5】:

    如果您不介意将版本写入临时文件,还有另一种解决方案(没有 grep/sed)对我很有效。 (编辑:请参阅rjrjr's answer 以获得更简单的解决方案,无需任何临时文件麻烦)

    我使用Exec Maven Pluginecho 二进制文件。与 Maven Help Plugin 相比,Exec Plugin 允许将输出重定向到文件中,该文件可用于绕过 grep/sed,甚至可以解析多行版本字符串等奇怪的东西(版本标签中带有 CDATA 块),至少在一定程度上。

    #!/usr/bin/env sh
    
    MVN_VERSION=""
    VERSION_FILE=$( mktemp mvn_project_version_XXXXX )
    trap "rm -f -- \"$VERSION_FILE\"" INT EXIT
    
    mvn -Dexec.executable="echo" \
        -Dexec.args='${project.version}' \
        -Dexec.outputFile="$VERSION_FILE" \
        --non-recursive \
        --batch-mode \
        org.codehaus.mojo:exec-maven-plugin:1.3.1:exec > /dev/null 2>&1 ||
        { echo "Maven invocation failed!" 1>&2; exit 1; }
    
    # if you just care about the first line of the version, which will be
    # sufficent for pretty much every use case I can imagine, you can use
    # the read builtin
    [ -s "$VERSION_FILE" ] && read -r MVN_VERSION < "$VERSION_FILE"
    
    # Otherwise, you could use cat.
    # Note that this still has issues when there are leading whitespaces
    # in the multiline version string
    #MVN_VERSION=$( cat "$VERSION_FILE" )
    
    printf "Maven project version: %s\n" "$MVN_VERSION"
    

    【讨论】:

    • 这是一个比辅助插件更好的解决方案,而且你不需要所有的 i/o。只需添加一个 -q 标志,唯一的输出就是版本。所以: mvn -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive org.codehaus.mojo:exec-maven-plugin:1.3.1:exec跨度>
    • rjrjr:太好了!我在这里唯一需要提到的是错误处理:如果 mvn 失败,你会得到一个无效的版本字符串。因此需要进行一些验证,例如检查 mvn 返回码或字符串本身。
    【解决方案6】:

    易于理解的多合一解决方案,输出 maven 项目版本,并抑制来自 [INFO]Download 消息的无关输出:

    mvn -o org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\['
    

    同样的东西,但分成两行:

    mvn -o org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate \
          -Dexpression=project.version | grep -v '\['
    

    输出:4.3-SNAPSHOT

    所以,在一个简单的 bash 脚本中使用您的 project.version

    projectVersion=`mvn -o org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -v '\['`
    cd "target/"$projectVersion"-build"
    

    此页面上的其他解决方案似乎并未将所有技巧合二为一。

    【讨论】:

      【解决方案7】:

      Tom 使用Exec Maven Plugin 的解决方案要好得多,但仍然比它需要的复杂。对我来说很简单:

      MVN_VERSION=$(mvn -q \
          -Dexec.executable=echo \
          -Dexec.args='${project.version}' \
          --non-recursive \
          exec:exec)
      

      【讨论】:

      • 我认为这是最简单的方法,因为它并不意味着使用 grep 或类似的东西。快速说明:您可以缩短一点:mvn -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive exec:exec
      • 这个解决方案对我很有效,因为我想打印 groupId、artifactId 和 version..-Dexec.args='${project.groupId}:${project.artifactId}:${project.version}'.
      • [ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.3.2:exec (default-cli) on project audit-events-processor-parent: Command execution failed. Cannot run program "maven" (in directory "/tmp"): error=2, No such file or directory shrug 又一个对我不起作用的答案,哦,好吧
      • 谢谢,这是迄今为止我见过的最好的解决方案,因为它不需要应用脆弱的 grep/sed 命令或类似的命令
      • 什么是set -o errexit
      【解决方案8】:

      应该更容易,因为这个错误已在 maven-help-plugin 3.0.0 中修复:MPH-99 Evaluate has no output in quiet mode

      【讨论】:

      • 遗憾的是 3.0.0 没有发布
      【解决方案9】:
      python -c "import xml.etree.ElementTree as ET; \
        print(ET.parse(open('pom.xml')).getroot().find( \
        '{http://maven.apache.org/POM/4.0.0}version').text)"
      

      只要你有 python 2.5 或更高版本,这应该可以工作。如果您的版本低于该版本,请安装 python-lxml 并将导入更改为 lxml.etree。这种方法很快,不需要下载任何额外的插件。它也适用于不使用 xmllint 验证的格式错误的 pom.xml 文件,例如我需要解析的文件。在 Mac 和 Linux 上测试。

      【讨论】:

        【解决方案10】:
        VERSION=$(head -50 pom.xml | awk -F'>' '/SNAPSHOT/ {print $2}' | awk -F'<' '{print $1}')
        

        这是我用来获取版本号的,认为会有更好的maven方式来做到这一点

        【讨论】:

          【解决方案11】:

          我最近开发了 Release Candidate Maven 插件来解决这个确切的问题,这样您就不必求助于任何 hacky shell 脚本并解析 maven-help-plugin 的输出。

          例如,要将 Maven 项目的版本打印到终端,请运行:

          mvn com.smartcodeltd:release-candidate-maven-plugin:LATEST:version
          

          其输出类似于maven-help-plugin:

          [INFO] Detected version: '1.0.0-SNAPSHOT'
          1.0.0-SNAPSHOT
          [INFO] ------------------------------------------------------------------------
          [INFO] BUILD SUCCESS
          [INFO] ------------------------------------------------------------------------
          

          但是,您也可以指定任意输出格式(以便 CI 服务器可以从日志中获取版本,例如 TeamCity):

          mvn com.smartcodeltd:release-candidate-maven-plugin:LATEST:version \
             -DoutputTemplate="##teamcity[setParameter name='env.PROJECT_VERSION' value='{{ version }}']"
          

          结果:

          [INFO] Detected version: '1.0.0-SNAPSHOT'
          ##teamcity[setParameter name='env.PROJECT_VERSION' value='1.0.0-SNAPSHOT']
          [INFO] ------------------------------------------------------------------------
          [INFO] BUILD SUCCESS
          [INFO] ------------------------------------------------------------------------
          

          将输出保存到文件中(以便Jenkins 等 CI 服务器可以use it):

          mvn com.smartcodeltd:release-candidate-maven-plugin:LATEST:version \
             -DoutputTemplate="PROJECT_VERSION={{ version }}" \
             -DoutputUri="file://\${project.basedir}/version.properties"
          

          生成的version.properties 文件如下所示:

          PROJECT_VERSION=1.0.0-SNAPSHOT
          

          除此之外,Release Candidate 还允许您根据您的 API 版本设置项目的版本(您可能会在 CI 服务器上执行此操作) '已在您的 POM 中定义。

          如果您想查看将候选版本用作 Maven 生命周期一部分的示例,请查看我的另一个开源项目的 pom.xml - Build Monitor for Jenkins

          【讨论】:

            【解决方案12】:

            这对我有用,离线且不依赖于 mvn:

            VERSION=$(grep --max-count=1 '<version>' <your_path>/pom.xml | awk -F '>' '{ print $2 }' | awk -F '<' '{ print $1 }')
            echo $VERSION
            

            【讨论】:

              【解决方案13】:

              Exec 插件无需任何输出解析即可工作,因为可以将输出重定向到文件并通过 EnvInject 插件注入回作业环境:

              【讨论】:

                【解决方案14】:

                这将避免从输出中删除日志条目的需要:

                mvn -Dexec.executable='echo' -Dexec.args='${project.version}' --non-recursive exec:exec -q
                

                【讨论】:

                • 虽然此代码可能会回答问题,但提供有关 why 和/或 如何 它回答问题的额外上下文将显着改善其长期价值。请edit你的答案添加一些解释。
                • 我认为对于这种方法,有必要在 mvn 之后加上“-q”。
                • 这比公认的解决方案要好;无需过滤掉 Maven 噪声输出。
                【解决方案15】:

                在我看来,最重要的答案是相当垃圾,你必须使用一堆 grep 来破解 maven 控制台输出。为什么不使用正确的工具来完成这项工作?使用 xpath 语法是检索版本号的最佳方法,因为它是访问 XML 数据结构的预期方法。下面的表达式使用元素的“本地名称”遍历 pom,换句话说,忽略了 xml 中可能存在或不存在的命名空间声明。

                xmllint --xpath "//*[local-name()='project']/*[local-name()='version']/text()" pom.xml
                

                【讨论】:

                • @bobmarksie 我同意这一点;使用 maven 并用正则表达式擦洗输出是很痛苦的。
                • 从父 pom 继承的项目怎么样。
                • “为什么不使用正确的工具来完成这项工作?” IE !Maven?
                • 我知道使用mvn 是正确的方法,exec 插件实际上工作得很好,但是所有 mvn 解决方案都必须解决,我正在尝试引导一个构建管道,其中依赖解决不会工作,所以我将用这个解决方案替换exec 方法。幸运的是,我不必担心从父母那里继承的版本。
                • 这不适用于 ci 友好的版本控制,例如,版本是像 ${revision} 这样的属性。参考。 maven.apache.org/maven-ci-friendly.html
                【解决方案16】:

                在此处使用其他一些答案时,我一直遇到附带情况,所以这里还有另一种选择。

                version=$(printf 'VER\t${project.version}' | mvn help:evaluate | grep '^VER' | cut -f2)
                

                【讨论】:

                • printf 'VER\t${project.version}' | mvn help:evaluate 2&gt; /dev/null | grep '^VER' | cut -f2
                【解决方案17】:

                为了记录,可以直接在命令行中配置Maven的Simple SLF4J logging,通过配置只输出我们需要的:

                • org.slf4j.simpleLogger.defaultLogLevel=WARN
                • org.slf4j.simpleLogger.log.org.apache.maven.plugins.help=INFO

                如记录在http://www.slf4j.org/api/org/slf4j/impl/SimpleLogger.html

                MAVEN_OPTS="\
                -Dorg.slf4j.simpleLogger.defaultLogLevel=WARN \
                -Dorg.slf4j.simpleLogger.log.org.apache.maven.plugins.help=INFO" \
                mvn help:evaluate -o -Dexpression=project.version
                

                因此,可以简单地运行tail -1 并获得:

                $ MAVEN_OPTS="\
                -Dorg.slf4j.simpleLogger.defaultLogLevel=WARN \
                -Dorg.slf4j.simpleLogger.log.org.apache.maven.plugins.help=INFO" \
                mvn help:evaluate -o -Dexpression=project.version | tail -1
                
                1.0.0-SNAPSHOT
                

                请注意,这是一个单行。 MAVEN_OPTS 仅针对此特定的 mvn 执行重写。

                【讨论】:

                  【解决方案18】:

                  要么你有mvn 给你答案(正如大多数答案所暗示的那样),要么你从pom.xml 中提取答案。第二种方法的唯一缺点是您可以很容易地提取 &lt;version/&gt; 标记的值,但只有当它是 literal 时才有意义,即不是 Maven 属性。我还是选择了这种方法,因为:

                  • mvn 是一种冗长的方式,我只是不喜欢过滤它的输出。
                  • 与读取pom.xml 相比,启动mvn 非常慢。
                  • 我总是在 &lt;version/&gt; 中使用文字值。

                  mvn-version 是一个zsh shell 脚本,它使用xmlstarlet 读取pom.xml 并打印项目的版本(如果存在)或父项目的版本(如果存在):

                  $ mvn-version .
                  1.0.0-SNAPSHOT
                  

                  优点是它方式比运行mvn快:

                  $ time mvn-version .
                  1.1.0-SNAPSHOT
                  mvn-version .  0.01s user 0.01s system 75% cpu 0.019 total
                  
                  $ time mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate \
                  > -Dexpression=project.version
                  mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate   4.17s user 0.21s system 240% cpu 1.823 total
                  

                  我的机器上的差异大于两个数量级。

                  【讨论】:

                    【解决方案19】:

                    一个简单的 Maven 唯一解决方案

                    mvn -q -N org.codehaus.mojo:exec-maven-plugin:1.3.1:exec \
                        -Dexec.executable='echo' \
                        -Dexec.args='${project.version}'
                    

                    对于奖励积分,解析部分版本

                    mvn -q -N org.codehaus.mojo:build-helper-maven-plugin:3.0.0:parse-version \
                        org.codehaus.mojo:exec-maven-plugin:1.3.1:exec \
                        -Dexec.executable='echo' \
                        -Dexec.args='${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}'
                    

                    【讨论】:

                      【解决方案20】:

                      在做了一些研究后,我发现了以下内容:

                      1. Maven 受到指责是因为与 DevOps 工具的集成并不容易,因为它没有遵循有关 CLI 工具的一些良好实践,即:

                      http://www.faqs.org/docs/artu/ch01s06.html(不再可用) “Unix 方式” (ii) 期望每个程序的输出成为另一个未知程序的输入。不要用无关信息使输出混乱。避免严格的列式或二进制输入格式。不要坚持交互式输入。 它实际上是什么意思? 你的输出应该是:

                      • “grepable”:(每行一个“记录”)
                      • “cutable”:(分隔的“字段”)
                      • 退出代码:0 表示成功,非零表示失败。
                      • 消息(stderr)与输出(stdout)

                      (参考:Dave Copeland 用 ruby​​ 制作很棒的命令行应用程序,2012 年 1 月 18 日https://youtu.be/1ILEw6Qca3U?t=372

                      1. 诚实我认为 Dave Copeland 说 maven 不公平对待他人是正确的。所以我决定看看 maven 的源代码以及 maven-help-plugin 的源代码。似乎他们已经修复了一些 maven 的 -q 开关(当时我使用的是 3.5.3 版),所以现在如果你通过它,你将不会得到所有阻止 maven 的烦人的无意义日志记录的东西从在自动化脚本中使用。所以你应该可以使用这样的东西:

                        mvn help:evaluate -Dexpression=project.version -q
                        

                      问题是这个命令没有打印任何内容,因为默认情况下,帮助插件通过 -q 开关静音的记录器输出。 (当时该插件的最新可用版本是 2018 年 6 月 3 日发布的 3.1.0)

                      1. Karl Heinz Marbaise (https://github.com/khmarbaise) 通过添加一个允许您以下列方式调用它的可选参数来修复它:

                        mvn help:evaluate -Dexpression=project.version -q -DforceStdout
                        

                      提交说明位于:(https://github.com/apache/maven-help-plugin/commit/316656983d780c04031bbadd97d4ab245c84d014)

                      同样,您应该始终验证命令的退出代码并将所有 stderr 重定向到 unix 上的 /dev/null。

                      【讨论】:

                      • 这将是我的首选解决方案,官方help pages也有提及。但是,它对我不起作用。我在使用 Maven v3.5.3 的 MacOS 上。当我不使用-q 开关时,它会正确打印出版本(在日志行之间)。有什么想法吗?
                      • 这应该是公认的答案。它适用于 Windows 和 Linux(我没有尝试过 Max OSX),而且很简单。谢谢。
                      • @montoyaedu 抱歉没有回复。与此同时,我已经更新到 maven 3.5.4,它可以很好地与 -q 开关配合使用。
                      • @gucce 我可以确认使用的 maven 版本会影响这一点:使用 3.5.2(debian 9 上的软件包版本)时,-q -DforceStdout 的输出是空的,即使确保插件的 3.1.0 版本是与 pluginManagement 一起使用);我用 3.5.4 版的 maven 配置了 maven 包装器,它工作正常
                      • 最后,2019 年没有 grep 的实用解决方案 - (这应该成为公认的答案)。也适用于 CI-friendly versions - 在 3.3.9、3.5.3、3.5.4、3.6.0 上测试
                      【解决方案21】:

                      我找到了适合自己的平衡点。在mvn package maven-archiver 插件创建target/maven-archiver/pom.properties 后,内容如下

                      version=0.0.1-SNAPSHOT
                      groupId=somegroup
                      artifactId=someArtifact
                      

                      我使用 bash 只是为了执行它

                      . ./target/maven-archiver/pom.properties
                      

                      然后

                      echo $version
                      0.0.1-SNAPSHOT
                      

                      当然执行这个文件是不安全的,但是执行可以很容易地转换成 perl 或 bash 脚本来从那个文件读取和设置环境变量。

                      【讨论】:

                        【解决方案22】:

                        我在我的 unix shell 中使用单线...

                        猫 pom.xml | grep "" |头-n 1 | sed -e "s/版本//g" | sed -e "s/\s*[/]*//g"

                        您可以将此行隐藏在 shell 脚本中或作为别名。

                        【讨论】:

                          【解决方案23】:

                          这是上面的编辑

                          猫 pom.xml | grep "" |头-n 1 | sed -e "s/版本//g" | sed -e "s/\s*[/]*//g"

                          我在 cmdline 上进行了测试,效果很好

                          grep "" pom.xml |头-n 1 | sed -e "s/版本//g" | sed -e "s/\s*[/]*//g"

                          是相同的另一个版本。我需要在没有安装 mvn 的情况下在 k8s 中获取 Jenkins CI 中的版本号,所以这是最有帮助的

                          谢谢大家。

                          【讨论】:

                          • 如果你有一个父 POM 怎么办?如果依赖项异常地放在项目的 GAV 之前怎么办?
                          【解决方案24】:

                          还有一个选项不需要Maven:

                          grep -oPm1 "(?<=<version>)[^<]+" "pom.xml"
                          

                          【讨论】:

                          • 这个只显示pom中的第一次出现。在我的情况下,第一次出现给出了父 pom 版本。但老实说,这是我一直在寻找的答案。它比前面提到的解决方案要快得多,并且很容易修改它以获得正确的发生。为了获得第二次出现使用:grep -oPm2 "(?&lt;=&lt;version&gt;)[^&lt;]+" pom.xml | sed -n 2p 为了获得第三次出现使用:grep -oPm3 "(?&lt;=&lt;version&gt;)[^&lt;]+" pom.xml | sed -n 3p 等等
                          • 你假设版本元素是第一次出现,当假设无效时它不起作用。
                          【解决方案25】:

                          这是最干净的解决方案

                          mvn org.apache.maven.plugins:maven-help-plugin:3.2.0:evaluate \
                          -Dexpression=project.version -q -DforceStdout
                          

                          优点:

                          • 这适用于所有操作系统和所有 shell。
                          • 无需任何外部工具!
                          • [important] 即使项目版本是从父 pom.xml 继承的,这仍然有效

                          注意:

                          • maven-help-plugin 版本 3.2.0(及更高版本)具有 forceStdout 选项。如果可用,您可以将上述命令中的 3.2.0 替换为来自 artifactory 的 available versions of mvn-help-plugin 列表中的更新版本。
                          • 选项-q 抑制详细消息([INFO][WARN] 等)

                          或者,您可以在pom.xmlplugins 部分下添加此条目:

                          <plugin>
                              <groupId>org.apache.maven.plugins</groupId>
                              <artifactId>maven-help-plugin</artifactId>
                              <version>3.2.0</version>
                          </plugin>
                          

                          然后紧凑地运行上面的命令如下:

                          mvn help:evaluate -Dexpression=project.groupId -q -DforceStdout
                          

                          如果您还想获取groupIdartifactId,请检查this answer

                          【讨论】:

                          • 这是恕我直言的最佳答案,因为所有其他人都没有指出(因为我发现很难)你需要至少 3.1.0 版的 maven-help-plugin 因为否则-DforceStdout 选项will be unknown 并运行“mvn -q help:evaluate ....”将不会产生任何输出。
                          【解决方案26】:

                          我在 Travis 工作期间确实需要这个要求,但有多个值。 我从this solution 开始,但多次调用时速度很慢(我需要 5 个表达式)。

                          我编写了一个简单的 maven 插件来将 pom.xml 的值提取到 .sh 文件中。

                          https://github.com/famaridon/ci-tools-maven-plugin

                          mvn com.famaridon:ci-tools-maven-plugin:0.0.1-SNAPSHOT:environment -Dexpressions=project.artifactId,project.version,project.groupId,project.build.sourceEncoding
                          

                          将产生:

                          #!/usr/bin/env bash
                          CI_TOOLS_PROJECT_ARTIFACTID='ci-tools-maven-plugin';
                          CI_TOOLS_PROJECT_VERSION='0.0.1-SNAPSHOT';
                          CI_TOOLS_PROJECT_GROUPID='com.famaridon';
                          CI_TOOLS_PROJECT_BUILD_SOURCEENCODING='UTF-8';
                          

                          现在您可以简单地获取文件

                          source .target/ci-tools-env.sh
                          

                          玩得开心。

                          【讨论】:

                            【解决方案27】:

                            这是迄今为止最简单的 bash 剪切和粘贴解决方案:

                            VERSION=$(mvn exec:exec -Dexec.executable='echo' -Dexec.args='${project.version}' --non-recursive -q)
                            echo $VERSION
                            

                            它回响

                            1.4
                            

                            【讨论】:

                            • 未知生命周期阶段“.executable=echo”。您必须以格式指定有效的生命周期阶段或目标
                            • @chokdee 你用的是哪个版本的maven?
                            • 3.6.1 在 Windows 上
                            • @chokdee 你必须写整行直到exec:exec。当 plugin:goal 部分 exec:exec 部分丢失时会发生错误
                            • 我确实做到了。同样的错误。也许它没有在 Windows 上运行?
                            【解决方案28】:

                            基于这个问题,我使用下面的这个脚本来自动增加我在所有 maven 父/子模块中的版本号:

                            #!/usr/bin/env bash  
                            
                            # Advances the last number of the given version string by one.  
                            function advance\_version () {  
                                local v=$1  
                                \# Get the last number. First remove any suffixes (such as '-SNAPSHOT').  
                              local cleaned=\`echo $v | sed \-e 's/\[^0-9\]\[^0-9\]\*$//'\`  
                             local last\_num=\`echo $cleaned | sed \-e 's/\[0-9\]\*\\.//g'\`  
                             local next\_num=$(($last\_num+1))  
                              \# Finally replace the last number in version string with the new one.  
                              echo $v | sed \-e "s/\[0-9\]\[0-9\]\*\\(\[^0-9\]\*\\)$/$next\_num/"  
                            }  
                            
                            version=$(mvn org.apache.maven.plugins:maven-help-plugin:3.2.0:evaluate -Dexpression=project.version -q -DforceStdout)  
                            
                            new\_version=$(advance\_version $version)  
                            
                            mvn versions:set -DnewVersion=${new\_version} -DprocessAllModules -DgenerateBackupPoms=false
                            

                            【讨论】:

                              【解决方案29】:

                              另一种方法是使用 yq (https://github.com/kislyuk/yq) 解析,如下所示:

                              cat pom.xml | xq -r '.project.version'
                              

                              注意可执行文件是 xq 而不是 yq

                              要获取 xq,请像这样安装 yq pip install yq

                              【讨论】:

                                【解决方案30】:

                                在只有 busybox 可用的 docker 容器中,我使用 awk。

                                version=$(
                                 awk '
                                  /<dependenc/{exit}
                                  /<parent>/{parent++};
                                  /<version>/{
                                    if (parent == 1) {
                                      sub(/.*<version>/, "");
                                      sub(/<.*/, "");
                                      parent_version = $0;
                                    } else {
                                      sub(/.*<version>/, "");
                                      sub(/<.*/, "");
                                      version = $0;
                                      exit
                                    }
                                  }
                                  /<\/parent>/{parent--};
                                  END {
                                    print (version == "") ? parent_version : version
                                  }' pom.xml
                                )
                                

                                注意事项:

                                • 如果没有给出工件版本,则会打印父版本。
                                • 依赖项必须位于工件和父版本之后。 (这可以很容易地克服,但我不需要它。)

                                【讨论】:

                                  猜你喜欢
                                  • 2014-06-24
                                  • 1970-01-01
                                  • 2019-06-11
                                  • 2021-04-30
                                  • 1970-01-01
                                  • 2023-03-30
                                  • 2017-12-19
                                  • 2023-04-08
                                  相关资源
                                  最近更新 更多