私は2つのディレクトリを持っています
$ tree dir{1..2}
dir1
├── file1
└── file2
dir2
├── file1
└── file2
ansibleを使用してdir1のすべてのファイルをdir2のすべてのファイルと比較し、次のように違いを印刷したいと思います。
output:
${file1} from ${dir1}:
diff content
${file1} from ${dir2}:
diff content
すべてのファイルを繰り返して違いを印刷します。
以下は、修正する必要のあるansibleスニペットです。
---
- name: Compare files in two directories
hosts: localhost
gather_facts: false
tasks:
- name: Find files in directory 1
find:
paths: ~/dir1
file_type: file
register: dir1_files
- name: Find files in directory 2
find:
paths: ~/dir2
file_type: file
register: dir2_files
- name: Compare files
shell: diff dir1/file1 dir2/file1 ## how can I make sure path changes but filenames stay same using variables
loop: "{{ dir1_files.files }}"
register: diff_output
changed_when: false
failed_when: diff_output.rc == 1
- name: Print differences
debug:
msg: |
{{ item.item.path }} from dir1:
{{ item.stdout }}
{{ item.item.path }} from dir2:
{{ item.stdout }}
loop: "{{ diff_output.results }}"
when: item.stdout_lines | length > 0
Vladimirの回答で提案されたコードについては、次の結果が表示されます。
TASK [debug] *****************************************************************************************************************************************
ok: [localhost] => {
"msg": "file2 from dir1: \n 1,2c1,2\n < abc123\n < def456\n ---\n > abc101\n > def111\nfile2 from dir2: \n 1,2c1,2\n < abc123\n < def456\n ---\n > abc101\n > def111\nfile1 from dir1: \n 1,2c1,2\n < 123abc\n < 456def\n ---\n > 101abc\n > 111def\nfile1 from dir2: \n 1,2c1,2\n < 123abc\n < 456def\n ---\n > 101abc\n > 111def\n"
}
答え1
たとえば、与えられたファイル
shell> ssh admin@test_11 ls -1 /tmp/dir[1,2]
/tmp/dir1:
file1
file2
/tmp/dir2:
file1
file2
shell> ssh admin@test_13 ls -1 /tmp/dir[1,2]
/tmp/dir1:
/tmp/dir2:
そして違い
shell> ssh admin@test_11 diff /tmp/dir1/file1 /tmp/dir2/file1
31,32d30
< User1:*:1002:1004:My User1:/home/User1:/bin/sh
< MyUser1:*:1003:1005:My User1:/home/MyUser1:/bin/sh
shell> ssh admin@test_11 diff /tmp/dir1/file2 /tmp/dir2/file2
33,34d32
< alice:*:1004:1006:Alice:/home/alice:/bin/sh
< bob:*:1005:1007:Bob:/home/bob:/bin/sh
変数宣言
dir1: /tmp/dir1
dir2: /tmp/dir2
dir1_files: "{{ out_dir1.files|map(attribute='path') }}"
dir2_files: "{{ out_dir2.files|map(attribute='path') }}"
そしてファイルを探す
- find:
paths: "{{ dir1 }}"
file_type: file
register: out_dir1
- find:
paths: "{{ dir2 }}"
file_type: file
register: out_dir2
共有ファイルを探します。変数宣言
files_common: "{{ dir1_files|map('basename')|
intersect(dir2_files|map('basename')) }}"
test_11とtest_13をそれぞれ提供します(要約)。
files_common:
- file1
- file2
files_common: []
共有ファイルを比較してください。これらのエラーは無視する必要があります。違い返品RC=1ファイルが異なる場合
- command: "diff {{ dir1 }}/{{ item }} {{ dir2 }}/{{ item }}"
loop: "{{ files_common }}"
ignore_errors: true
register: out_diff
レポートを作成し、
- debug:
msg: |
{% for i in out_diff.results %}
{{ i.cmd|join(' ') }}: |
{{ i.stdout|indent(2) }}
{% endfor %}
test_11とtest_13をそれぞれ提供します(要約)。
msg: |-
diff /tmp/dir1/file1 /tmp/dir2/file1: |
31,32d30
< User1:*:1002:1004:My User1:/home/User1:/bin/sh
< MyUser1:*:1003:1005:My User1:/home/MyUser1:/bin/sh
diff /tmp/dir1/file2 /tmp/dir2/file2: |
33,34d32
< alice:*:1004:1006:Alice:/home/alice:/bin/sh
< bob:*:1005:1007:Bob:/home/bob:/bin/sh
msg: ""
テストのための完全なプレイブックの例
- hosts: all
vars:
dir1: /tmp/dir1
dir2: /tmp/dir2
dir1_files: "{{ out_dir1.files|map(attribute='path') }}"
dir2_files: "{{ out_dir2.files|map(attribute='path') }}"
files_common: "{{ dir1_files|map('basename')|
intersect(dir2_files|map('basename')) }}"
tasks:
- find:
paths: "{{ dir1 }}"
file_type: file
register: out_dir1
- find:
paths: "{{ dir2 }}"
file_type: file
register: out_dir2
- debug:
var: files_common
- command: "diff {{ dir1 }}/{{ item }} {{ dir2 }}/{{ item }}"
loop: "{{ files_common }}"
ignore_errors: true
register: out_diff
- debug:
msg: |
{% for i in out_diff.results %}
{{ i.cmd|join(' ') }}: |
{{ i.stdout|indent(2) }}
{% endfor %}
尋ねる:「私はmsgモジュールの出力が好きではありません。Qが出力セクションで提供したものと似た形式を好みます。
答え:もちろんです。以下のテンプレートをお試しください。これが気に入らない場合は、質問を編集して希望の例を提供してください。
- debug:
msg: |
{% for i in out_diff.results %}
{{ i.cmd.1|basename }} from {{ i.cmd.1|dirname }}:
{{ i.stdout|indent(2) }}
{{ i.cmd.2|basename }} from {{ i.cmd.2|dirname }}:
{{ i.stdout|indent(2) }}
{% endfor %}
出力形式はコールバックによって異なります。バラよりDEFAULT_STDOUT_CALLBACK。使用する場合ansible.buildin.defaultコールバック設定 ANSIBLE_CALLBACK_RESULT_FORMAT=yaml
shell> ANSIBLE_STDOUT_CALLBACK=default ANSIBLE_CALLBACK_RESULT_FORMAT=yaml ansible-playbook pb.yml
...
ok: [test_11] =>
msg: |-
file1 from /tmp/dir1:
31,32d30
< User1:*:1002:1004:My User1:/home/User1:/bin/sh
< MyUser1:*:1003:1005:My User1:/home/MyUser1:/bin/sh
file1 from /tmp/dir2:
31,32d30
< User1:*:1002:1004:My User1:/home/User1:/bin/sh
< MyUser1:*:1003:1005:My User1:/home/MyUser1:/bin/sh
file2 from /tmp/dir1:
33,34d32
< alice:*:1004:1006:Alice:/home/alice:/bin/sh
< bob:*:1005:1007:Bob:/home/bob:/bin/sh
file2 from /tmp/dir2:
33,34d32
< alice:*:1004:1006:Alice:/home/alice:/bin/sh
< bob:*:1005:1007:Bob:/home/bob:/bin/sh
ok: [test_13] =>
msg: ""
バラより
shell> ansible-doc -t callback ansible.builtin.default