local_action:shell 错误连接文件 [英] local_action: shell error concatenate files
问题描述
我的剧本中有这样一个错误.为什么以及如何修复它?(获取远程主机的更新列表,将列表连接到一个文件中)
There is such an error in my playbook. Why and how to fix it? (getting the list of updates of remote-hosts, concatenate lists into one file)
- 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) 文件存在且为真后.
directory ~/tmp
is empty. After shell result file (list_update) file exists and true.
推荐答案
您使用 glob ~/tmp/*
并且其中一个文件是 ~/tmp/list_update
,因此您可以有效地命令它通过重定向读取和写入同一个文件,而系统拒绝这样做.
You use a glob ~/tmp/*
and one of the files is ~/tmp/list_update
, so effectively you order it to read and write to the same file with a redirection and system is refusing to do that.
您也没有指定 run_once
,因此 一次合并来自不同主机的文件
任务将运行,因为有为播放定义的主机.
You also didn't specify run_once
, so the merge files from different hosts in once
task will run as there are hosts defined for the play.
如果您确定 ~/tmp/list_update
事先不存在,则向该任务添加 run_once: true
可以解决问题,但还差得很远以最好的方式.
If you are sure ~/tmp/list_update
didn't exist beforehand, adding run_once: true
to that task would resolve the problem, but it's far from the best way.
长话短说,例如,您可以在一项任务中实现您想要的
Long story short, you can achieve what you want in one task, for example
使用 Jinja2 模板:
with a Jinja2 template:
- 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
-value 添加分隔符以指示哪些数据来自哪个主机:
You can add separators with host
-value to indicate what data is coming from which host:
content: "{% for host in ansible_play_hosts %}From host: {{ host }}\n{{ hostvars[host].update_deb_packs.stdout }}\n{% endfor %}"
在列表上使用操作:
using operations on lists:
content: "{{ ansible_play_hosts | map('extract', hostvars, 'update_deb_packs') | map(attribute='stdout') | list }}"
这篇关于local_action:shell 错误连接文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!