我的剧本中有这样的错误。为什么以及如何解决它? (获取远程主机的更新列表,将列表连接到一个文件中)
- name: Save update_deb_packs in file on ansible-host
copy:
content: "{{ update_deb_packs.stdout }}"
dest: ~/tmp/{{ inventory_hostname }}_update_deb_packs
delegate_to: 127.0.0.1
- name: merge files from different hosts in once
local_action: shell cat ~/tmp/* > ~/tmp/list_update
结果:
TASK [Save update_deb_packs in file on ansible-host] *******************************************
changed: [g33-linux -> 127.0.0.1]
changed: [dell-e6410 -> 127.0.0.1]
TASK [merge files from different hosts in once] ********************************
changed: [g33-linux -> localhost]
fatal: [dell-e6410 -> localhost]: FAILED! => {"changed": true, "cmd": "cat ~/tmp/* > ~/tmp/list_update", "delta": "0:00:00.052968", "end": "2017-12-23 13:48:37.029706", "msg": "non-zero return code", "rc": 1, "start": "2017-12-23 13:48:36.976738", "stderr": "cat: /home/alex/tmp/list_update: input and output in one file", "stderr_lines": ["cat: /home/alex/tmp/list_update: input and output in one file"], "stdout": "", "stdout_lines": []}
to retry, use: --limit @/home/alex/.ansible/playbooks/update_deb_list.retry
目录~/tmp
为空。 shell 结果文件(list_update)文件存在且为真。
答案 0 :(得分:0)
您使用了一个glob ~/tmp/*
,其中一个文件是~/tmp/list_update
,所以有效地命令它通过重定向读取和写入同一个文件,系统拒绝这样做。
您也没有指定run_once
,因此merge files from different hosts in once
任务将会运行,因为有为此游戏定义的主机。
如果您确定~/tmp/list_update
事先不存在,那么将run_once: true
添加到该任务可以解决问题,但这远不是最好的方法。< / em>的
简而言之,您可以在一项任务中实现您想要的目标,例如
使用Jinja2模板:
- copy:
content: "{% for host in ansible_play_hosts %}{{ hostvars[host].update_deb_packs.stdout }}\n{% endfor %}"
dest: ~/tmp/list_update
delegate_to: localhost
run_once: true
您可以添加host
- 值的分隔符,以指示哪些数据来自哪个主机:
content: "{% for host in ansible_play_hosts %}From host: {{ host }}\n{{ hostvars[host].update_deb_packs.stdout }}\n{% endfor %}"
使用列表上的操作:
content: "{{ ansible_play_hosts | map('extract', hostvars, 'update_deb_packs') | map(attribute='stdout') | list }}"