使用 Ansible 在服务器上检测所需的 grep

detect desired grep on server using Ansible

我的要求是在 Ansible 中使用 grep -E 选项。

如果服务器上存在 /usr/xpg4/bin/grep,我希望先使用它,否则切换到 /bin/grep

我正在寻找适用于各种 shell 和操作系统的 POSIX 解决方案。

以下命令在命令行上运行良好:

$ ls /usr/xpg4/bin/grep 2> >(grep -v 'No such file or directory' >&2) || ls /bin/grep 2> >(grep -v 'No
> such file or directory' >&2)

输出:

/usr/xpg4/bin/grep

我尝试在 Ansible 中使用上述解决方案,如下所示:

 - name: "Detect the grep on the system"
   ignore_errors: yes
   command:  "ls /usr/xpg4/bin/grep 2> >(grep -v 'No such file or directory' >&2) || ls /bin/grep 2> >(grep -v 'No     such file or directory' >&2 | head -1"
   register: grepfound

在输出中它找到了两个 grep 而不是获得一个首选 /usr/xpg4/bin/grep {{ grepfound.stdout }} 打印了我从来不想要的两个 grep。

输出:

fatal: [localhost]: FAILED! => {"changed": true, "cmd": ["ls", "/usr/xpg4/bin/grep", "2>", ">(grep", "-v", "No such file or directory", ">&2)", "||", "ls", "/bin/grep", "2>", ">(grep", "-v", "No such file or directory", ">&2"], "delta": "0:00:00.013219", "end": "2021-06-14 05:25:52.178385", "msg": "non-zero return code", "rc": 2, "start": "2021-06-14 05:25:52.165166", "stderr": "2>: No such file or directory\n>(grep: No such file or directory\n-v: No such file or directory\nNo such file or directory: No such file or directory\n>&2): No such file or directory\n||: No such file or directory\nls: No such file or directory\n2>: No such file or directory\n>(grep: No such file or directory\n-v: No such file or directory\nNo such file or directory: No such file or directory\n>&2: No such file or directory", "stderr_lines": ["2>: No such file or directory", ">(grep: No such file or directory", "-v: No such file or directory", "No such file or directory: No such file or directory", ">&2): No such file or directory", "||: No such file or directory", "ls: No such file or directory", "2>: No such file or directory", ">(grep: No such file or directory", "-v: No such file or directory", "No such file or directory: No such file or directory", ">&2: No such file or directory"], **"stdout": "/bin/grep\n/usr/xpg4/bin/grep"**, "stdout_lines": ["/bin/grep", "/usr/xpg4/bin/grep"]}
...ignoring

我尝试使用 {{ grepfound.stdout_lines[0] }} 作为解决方法,但如您所见,它打印的是 /bin/grep 而不是 /usr/xpg4/bin/grep。如果我使用 {{ grepfound.stdout_lines[1] }},它将在这里工作,但在只找到一个 grep 的地方失败。

I would have still liked your help use stdout_lines instead of stdout so that the processes show up better formatted segregated... each process in a new-line

这就是 | select 发挥作用的地方——它旨在过滤 jinja2 测试评估为 true 的列表项

- set_fact:
   example_data:
     stdout_lines:
     - 1111 nothing here
     - 2222 this one is httpd
     - 3333 this one is tomcat
     - 4444 again nothing
- debug:
    msg: |
      the things as a list are:
      {{ example_data.stdout_lines | select('search', '(tomcat|weblogic|httpd)') | list }}

      but you can also fold them back into one str:
      {{ example_data.stdout_lines | select('search', '(tomcat|weblogic|httpd)') | join(nl) }}
  vars:
    # this silliness is to work around a quirk of jinja2 where
    # | join("\n") literally uses `"\n"` to join items :-(
    nl: "\n"

产生

  msg: |-
    the things as a list are:
    ['2222 this one is httpd', '3333 this one is tomcat']

    but you can also fold them back into one str:
    2222 this one is httpd
    3333 this one is tomcat

不能只靠PATH吗?

- name: stuff
  environment:
    PATH: /usr/xpg4/bin:/usr/bin:/bin
  shell: cat something | grep stuff

如果第一个路径中不存在您的二进制文件,它将检查下一个路径。