我想使用 ansible 在文件中搜索字符串

我想使用 ansible 在文件中搜索字符串
- name: extract a word
            ansible.builtin.lineinfile:
                    path: /file/to/path/file.log
                    regexp: '^nodeagent stopped: (.*)'
                    line: 'nodeagent stopped'
            register: extracted
          - debug:
                  msg: 'The extracted word is {{ extracted.matched }}'

使用上面的代码片段,我尝试在文件中搜索此“nodeagent ceases”,但出现以下错误:

{"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'matched'

The error appears to be in '/home/a239255/testing/test-playbook/restart-test3.yml': line 10, column 13, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be: 

           register: extracted
      - debug:
        ^ here
"}

答案1

请注意,模块lineinfile模块(用于)管理文本文件中的行因此不是适合(实时)日志文件监控的方法(注:不幸的是几乎没有信息和进一步的描述)。

此外,该lineinfile模块不维护自己独特的除常见返回值之外的返回值。 所以注册变量将不会提供文件内容,甚至其部分内容。

你可能想做的是

---
- hosts: localhost
  become: false
  gather_facts: false

  vars:

    SEARCH_STRING: "nodeagent stopped"
    SEARCH_FILE: "test.log"

  tasks:

  - name: Search for string
    lineinfile:
      path: "{{ SEARCH_FILE }}"
      regexp: '^{{ SEARCH_STRING }}: (.*)'
      line: "SEARCH_STRING FOUND"
      state: present
    register: result
    # Since it is a reporting task
    changed_when: false
    failed_when: "'line replaced' in result.msg" # as it means SEARCH_STRING FOUND
    check_mode: true # to prevent changes and do a dry-run only

  - name: Show result, if not found
    debug:
      var: result
    when: "'line added' in result.msg" # as it means SEARCH_STRING NOT FOUND

如果您想从静态(日志)文件中提取特定字符串,则可以使用类似方法

---
- hosts: localhost
  become: false
  gather_facts: false

  tasks:

  - name: Read log file
    slurp:
      src: test.log
    register: log

  - name: Show log file
    debug:
      msg: "{{ log['content'] | b64decode }}"

  - name: Show first result
    debug:
      msg: "{{ log['content'] | b64decode | regex_findall('nodeagent stopped') | first }}"

这是从

类似问答

但针对不同的用例。

请注意,使用该slurp模块,您将通过网络将整个文件从远程节点传输到控制节点,以便对其进行处理并查找字符串。对于日志文件,这些文件通常有几 MB。因此,如果远程节点上的文件包含某个字符串,您可能只对信息感兴趣,因此只需要传输该类型的信息,true或者false


这意味着应避免使用上述方法,另一种方法更合适。在示例和 Bash 中执行处理,在远程节点上搜索字符串

grep 'not found' test.log; echo $?
1
grep 'nodeagent stopped' test.log; echo $?
nodeagent stopped: 0
nodeagent stopped: 1
0

Ansible 的一个最小示例剧本

---
- hosts: localhost
  become: false
  gather_facts: false

  vars:

    SEARCH_STRING: "nodeagent stopped"
    SEARCH_FILE: "test.log"

  tasks:

  - name: Search for string in file
    command:
      cmd: "grep '{{ SEARCH_STRING }}' {{ SEARCH_FILE }}"
    register: result
    # Since it is a reporting task
    # which needs to deliver a result in any case
    failed_when: result.rc != 0 and result.rc != 1
    check_mode: false
    changed_when: false

你可以检查返回值以及返回代码(rc01以及该字符串是否包含。

  - name: Show result, if any
    debug:
      var: result.stdout_lines
    when: result.rc == 0

如果你想管理 IBM WebSphere 应用程序,你可以查看特定的自定义模块,例如,因为似乎已经有一些,Ansible WebSphere

一组 Ansible 模块,可让您管理 IBM 软件包和 WebSphere 资源

如果搜索如何启动、停止或检查服务器节点代理,可以找到更多其他剧本示例。

答案2

错误很明显:

错误是:“dict object”没有属性“matched”

词典提取没有属性匹配。看一下字典并修复它。


问:"nodeagent stopped"“在文件中搜索此内容。”

答:例如,给定文件

shell> cat /tmp/file.log 
nodeagent started: 0
nodeagent stopped: 0
nodeagent started: 1
nodeagent stopped: 1

读取文件,拆分行,然后搜索对于模式

    - name: Read the file
      ansible.builtin.slurp:
        src: /tmp/file.log
      register: file_log

声明变量

  matched: "{{ file_log.content|b64decode|split('\n')|
               select('search', 'nodeagent stopped') }}"

给出

  matched:
  - 'nodeagent stopped: 0'
  - 'nodeagent stopped: 1'

完整测试剧本的示例

- hosts: localhost

  vars:

    error: {"msg": "The task includes an option with an undefined
    variable. The error was: 'dict object' has no attribute
    'matched'\n\nThe error appears to be in
    '/home/a239255/testing/test-playbook/restart-test3.yml': line 10,
    column 13, but may\nbe elsewhere in the file depending on the
    exact syntax problem.\n\nThe offending line appears to be:\n\n
    register: extracted\n - debug:\n ^ here\n"}
    
    # Search for this "nodeagent stopped" in a file
    matched: "{{ file_log.content|b64decode|split('\n')|
                 select('search', 'nodeagent stopped') }}"

  tasks:

#    - name: extract a word
#      ansible.builtin.lineinfile:
#        path: /file/to/path/file.log
#        regexp: '^nodeagent stopped: (.*)'
#        line: 'nodeagent stopped'
#      register: extracted
#    - debug:
#        msg: 'The extracted word is {{ extracted.matched }}'
    - debug:
        var: error

    - name: Read the file
      ansible.builtin.slurp:
        src: /tmp/file.log
      register: file_log

    - debug:
        var: file_log.content|b64decode

    - debug:
        var: matched

相关内容