DDStackoverflow
DDStackoverflow

Reputation: 643

Collect only binary files in ansible

I want to collect all the binary files not belonging to a particular user from a directory, I can collect all the files with

- name: Recursively find /tmp files.
  find:
    paths: /tmp
    
    recurse: yes

but how can I specifically collect binary files and ignoring rest of them, I have to stat each file. Is there a way to filter at the find step.

Cheers, DD

Upvotes: 1

Views: 1329

Answers (1)

yabberth
yabberth

Reputation: 505

I'm not sure if you can do it with ansible alone. But you can use the file CLI tool with the --mime flag.

user@ubuntu:~$ file --mime .bashrc 
.bashrc: text/plain; charset=us-ascii

If issued with a binary file

user@ubuntu:~$ file --mime /bin/bash 
/bin/bash: application/x-sharedlib; charset=binary

I would use this with the command module and check if the output contains charset=binary

user@ubuntu:~$ ansible -m command -a "file --mime .bashrc" 127.0.0.1
127.0.0.1 | CHANGED | rc=0 >>
.bashrc: text/plain; charset=us-ascii

autlan@ubuntu:~$ ansible -m command -a "file --mime /bin/bash" 127.0.0.1
127.0.0.1 | CHANGED | rc=0 >>
/bin/bash: application/x-sharedlib; charset=binary

I wrote a small playbook. In the folder is the playbook file itself and a copy of the /bin/bash binary

---
- name: find binaries
  hosts: 127.0.0.1
  tasks:
    - name: find all files
      find:
        paths: .
      register: list_of_files
    - name: find binaries
      command: file --mime {{ item.path }}
      register: vari
      loop: "{{list_of_files.files}}"
      
    - name: print
      debug:
        msg: "{{item.stdout_lines}}"
      loop: "{{vari.results}}"
      when: item.stdout_lines is search("binary")

Shortened output:

user@ubuntu:~/playground$ ansible-playbook finder.yml 

PLAY [find binaries] *********************************************************************************

TASK [Gathering Facts] *******************************************************************************
ok: [127.0.0.1]

TASK [find all files] ********************************************************************************
ok: [127.0.0.1]

TASK [find binaries] *********************************************************************************
changed: [127.0.0.1] => (item={'path': 'finder.yml', )
changed: [127.0.0.1] => (item={'path': 'bash', )

TASK [print] *****************************************************************************************
skipping: [127.0.0.1] => (item={'cmd': ['file', '--mime', 'finder.yml'], , 

'changed': True, 'invocation': ansible_loop_var': 'item'}) => {
    "msg": [
        "bash: application/x-sharedlib; charset=binary"
    ]
}

PLAY RECAP *******************************************************************************************
127.0.0.1                  : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

As you can see, the first file is skipped and only the message is printed if the file is a binary.

Upvotes: 2

Related Questions