如何检查文件列表的大小

How to check the size of a file list

使用Ansible,我需要检查目录中的文件是否大于50M。 我用 ls 的结果做了一个 set_fact 然后我循环统计所有文件。这可行,但当文件大于 50M 时,我无法解析结果以创建失败条件。

我这样做 :

  - shell: ls -1 "{{ logs_directory }}"*.log  
    register: list_logs
  - set_fact:
      list_logs: "{{ list_logs.stdout_lines }}"
  - debug:
      msg: "{{ list_logs}}"
  
  - name: Get size
    stat:
      path: "{{ item }}"
    with_items: "{{ list_logs }}"
    register: size_log

  - name: debug
    fail:
       msg: "Problem with log size > 50M"
    when: 'size_log.stat.size / 1024 / 1024 | int > 50'

如果我只有 1 个文件,它可以工作,但是如果有多个服务器和多个文件,它就不起作用...如何解析 size_log_result?

这里是一个输出示例 size_log :

ok: [192.168.1.2] => {
    "msg": {
        "changed": false,
        "msg": "All items completed",
        "results": [
            {
                "ansible_loop_var": "item",
                "changed": false,
                "failed": false,
                "invocation": {
                    "module_args": {
                        "path": "/var/logs/admin.log"
                    }
                },
                "item": "/var/logs/admin.log",
                "stat": {
                      "size": 21711,
                }
            },
            {
                "ansible_loop_var": "item",
                "changed": false,
                "failed": false,
                "invocation": {
                    "module_args": {
                          "path": "/var/logs/database.log"
                    }
                },
                "item": "/var/logs/database.log",
                "stat": {
                    "size": 11162,
                }          
            }
        ]
    }
}
ok: [192.168.1.5] => {
    "msg": {
        "changed": false,
        "msg": "All items completed",
        "results": [
            {
                "ansible_loop_var": "item",
                "changed": false,
                "failed": false,
                "invocation": {
                    "module_args": {
                             "path": "/var/logs/database.log"
                    }
                },
                "item": "/var/logs/database.log",
                "stat": {
                    "size": 128453958,
                }
            }
        ]
    }
}

在我看来你是在重新发明轮子,而 find module 似乎已经完美地回答了你的用例。

鉴于:

- hosts: localhost
  gather_facts: no

  tasks:
    ####
    ## You do not need this task, it is just to create a file
    ## big enough for demonstration purpose
    ####
    - community.general.filesize:
        path: /var/log/heavy.log
        size: 51m

    - find:
        paths: /var/log
        patterns: '*.log'
        size: 51m
      register: _logs

    - fail:
        msg: "Due to file(s): {{ _logs.files | map(attribute='path') | join(', ') }}"
      when: _logs.files | length > 0

这将产生:

PLAY [localhost] **************************************************************************************************

TASK [community.general.filesize] *********************************************************************************
ok: [localhost]

TASK [find] *******************************************************************************************************
ok: [localhost]

TASK [fail] *******************************************************************************************************
fatal: [localhost]: FAILED! => changed=false 
  msg: 'Due to file(s): /var/log/heavy.log'

PLAY RECAP ********************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0