在 Ansible 剧本中使用 sed 命令

Using sed command in Ansible playbook

我想使用下面的命令 return 我的 pom.xml 的版本,但它不起作用。

- name: ensure apache is at the latest version
    shell: "echo cat \/\/*[local-name()='project']\/*[local-name()='version'] | xmllint --shell pom.xml | sed '\/^\/ >/d' | sed 's/<[^>]*.//g'"
    register: ArtifactId
- debug: var=ArtifactId.stdout_lines

有人可以帮忙吗?

这更像是一个基本的 shell 问题,而不是 Ansible 问题。即使没有 ansible,该命令行也会产生错误:

$ echo cat \/\/*[local-name()='project']\/*[local-name()='version'] | xmllint --shell pom.xml | sed '\/^\/ >/d' | sed 's/<[^>]*.//g'
bash: syntax error near unexpected token `('

cat 命令的参数引用不充分,您似乎在转义正斜杠 (/),这是不必要的,实际上可能会导致问题。试试这个:

- hosts: localhost
  tasks:
    - shell: >
        echo cat '//*[local-name()="project"]/*[local-name()="version"]' |
        xmllint --shell pom.xml |
        sed '\/^\/ >/d' |
        sed 's/<[^>]*.//g'
      register: artifactId

    - debug:
        var: artifactId.stdout_lines

使用 > 折叠标量运算符可以避免引用级别,这使命令更易于管理。它还允许您将其格式化为更具可读性。

给定以下输入:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <version>4.0.0</version>
</project>

以上剧本结果:

TASK [command] *****************************************************************
changed: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "artifactId.stdout_lines": [
        "4.0.0"
    ]
}

虽然这可行,但您可能需要考虑使用某种 XPath 模块来代替 ansible。 This one 好像最近有 activity,虽然我自己没试过。