Ansible 可从输出中删除的变量

Ansible 可从输出中删除的变量,ansible,jinja2,ansible-template,Ansible,Jinja2,Ansible Template,我想从Ansible输出中提取一些单词。例如,我想从sudo monit status命令中提取粗体字(****),并将其存储在2个变量中(假设变量“A”表示OK,变量“B”表示正常运行时间),稍后将使用到Jinja2模板中: [ansible@server ~]$ sudo monit status Monit 5.25.1 uptime: 3m System 'server' status **OK** monitoring status

我想从Ansible输出中提取一些单词。例如,我想从
sudo monit status
命令中提取粗体字(****),并将其存储在2个变量中(假设变量“A”表示OK,变量“B”表示正常运行时间),稍后将使用到Jinja2模板中:

[ansible@server ~]$ sudo monit status
Monit 5.25.1 uptime: 3m

System 'server'
  status                       **OK**
  monitoring status            Monitored
  monitoring mode              active
  on reboot                    start
  load average                 [0.03] [0.07] [0.11]
  cpu                          0.1%us 0.2%sy 0.0%wa
  memory usage                 338.1 MB [18.4%]
  swap usage                   0 B [0.0%]
  uptime                       **29m**
  boot time                    Fri, 30 Mar 2018 11:56:12
  data collected               Fri, 30 Mar 2018 12:25:24
为了实现这一点,我启动了Ansible playbook,但通过这种方式,我从输出中获取了所有信息:

--- #Health check
- hosts: appserver
  connection: ssh 
  sudo: yes 
  user: ansible
  tasks:
  - name: Monitor the status
    shell: "{{item}}"
    with_items:
      - monit status 
    register: monitinfo
    tags: basic_monitoring
  - debug: var=monitinfo
你知道如何做到这一点吗

谢谢,


Romain

我认为有两种方法可以解决您的问题:

方法1:将shell输出转换为YAML或JSON,并使用from_YAML或from_JSON对其进行解析 在您的特定情况下,由于输出已经以键值方式预格式化,因此最方便的方法是将其转换为Ansible能够理解的格式(例如YAML/JSON)。例如,您可以通过使用
tail
删除不相关的行,然后对其余行使用。然后,使用将所有内容解析为可解析变量。例如:

- name: Fetch the monit status
  shell: "monit status | tail -n +3"
  register: monit_status_raw
- name: Extract monit variables
  set_fact:
     monit_status: "{{ monit_status_raw.stdout | regex_replace('\s\s([a-z]+\s[a-z]*)\s+', '\\1: ') | regex_replace('\s:', ':') | regex_replace('([a-z])\s([a-z])', '\\1_\\2')  | from_yaml }}"
- name: Show server status 
  debug: var=monit_status['status']
- name: Show server uptime
  debug: var=monit_status['uptime']
如果一切正常,
monit_status
变量应该包含
monit status
命令提供的所有变量的字典。您可以访问所需的变量,如上面示例中的调试命令所示。如果代码还不能工作,您可以调试regex_替换过滤器

- debug: msg="{{ monit_status_raw.stdout | regex_replace('\s\s([a-z]+\s[a-z]*)\s+', '\\1: ') | regex_replace('\s:', ':') | regex_replace('([a-z])\s([a-z])', '\\1_\\2')  | from_yaml }}"
并检查输出是否真的是YAML。否则,必须调整正则表达式,以便最终输出符合YAML

方法2:使用regex_搜索过滤器搜索所需的值 在类似的情况下,只需提取一个变量,或者如果无法使用
regex\u replace
轻松地将输出转换为JSON或YAML,则
regex\u search
过滤器将是正确的选择。在您的情况下,regex_搜索解决方案看起来与此类似:

- name: Fetch the monit status
  shell: "monit status | tail -n +3"
  register: monit_status_raw
- name: Extract monit variables
  set_fact:
     monit_status: "{{ monit_status_raw.stdout | regex_search('\s\sstatus\s+(.*)') }}"
     monit_uptime: "{{ monit_status_raw.stdout | regex_search('\s\suptime\s+(.*)') }}"
- name: Show server status 
  debug: var=monit_status
- name: Show server uptime
  debug: var=monit_uptime

提示:像这样的在线正则表达式测试人员可以帮助您找到正确的表达式。

从检查开始:您的解决方案可能有效,但正则表达式部分有故障。我试过很多东西,但似乎没有一件是相配的。你知道这个正则表达式是如何修复的吗?提前谢谢。我稍微调整了正则表达式示例,以便它们真正符合您的确切用例。如果我的答案对你有帮助,我很高兴你能投赞成票,并/或将其标记为你接受的答案。祝你好运这并不是完美的(在set_事实中仍然有一些错误,但我将在regex101.com中尝试更多)。谢谢你的提示当你找到丢失的部分时,如果你能用你的修复来编辑我的答案就太好了!