我想从 RHEL 7.5 上的 stdin 向 ansible-playbook 2.4.2.0 提供一个剧本,我发现这个帖子这看起来很有希望,但对我来说却不起作用:
$ cat ~/simple-ansible-playbook.yaml | ansible-playbook -i ~/inventory.yaml /dev/stdin
ERROR! Unable to retrieve file contents
Could not find or access '/dev/stdin'
$
我追踪到了这条消息/usr/lib/python2.7/site-packages/ansible/parsing/dataloader.py
:
if not self.path_exists(b_file_name) or not self.is_file(b_file_name):
raise AnsibleFileNotFound("Unable to retrieve file contents", file_name=file_name)
os.path.isfile()
返回False
字符/dev/stdin
特殊文件的符号链接:
$ ls -l /dev/stdin
lrwxrwxrwx. 1 root root 15 Nov 11 13:11 /dev/stdin -> /proc/self/fd/0
$ ls -Ll /dev/stdin
crw--w----. 1 stack tty 136, 3 Feb 15 07:45 /dev/stdin
有人知道如何让它工作吗?我不明白为什么它似乎对引用的帖子有用,但对我来说却不起作用。
更新
我觉得我理解得更清楚了。原文使用了这里的文件shell 显然会将其返回到常规文件中。在我的方法中,数据位于管道中。我没有意识到 shell 在这方面的行为有所不同:我认为这里的文件也会导致管道。所以至少我学到了一些关于差异的新知识,但显然,除非做出改变,否则我无法做我想做的事情ansible-playbook
。
答案1
我认为我必须咬紧牙关,将剧本放在一个临时的常规文件中,而不是通过标准输入来提供它。
答案2
原始帖子使用了一个 here document,shell 显然将其返回到常规文件中
管道版本在现代版本的 ansible 上运行良好(我只是使用了 heredoc 来使答案更简洁):
$ printf -- '- hosts: all\n tasks:\n - debug: msg=hello\n' | \
ansible-playbook -c local -i localhost, /dev/stdin
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
TASK [debug] *******************************************************************
ok: [localhost] =>
msg: hello
PLAY RECAP *********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0
$ ls -l /dev/stdin
lrwxrwxrwx 1 root root 15 Feb 15 16:44 /dev/stdin -> /proc/self/fd/0
$ ansible --version
ansible 2.7.7
config file = None
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python2.7/dist-packages/ansible
executable location = /usr/local/bin/ansible
python version = 2.7.15rc1 (default, Nov 12 2018, 14:31:15) [GCC 7.3.0]
所以解决方案解决您的问题的方法是升级到 ansible 的现代版本。
然而,我不想全都悲观失望,所以如果你坚持通过管道将数据输入到 ansible 中:使用以下方法将管道流序列化为文件tee
:
$ printf -- '- hosts: all\n tasks:\n - debug: msg=hello\n' | \
tee being-on-old-software-is-dangerous.yml | \
ansible-playbook -c local -i localhost, being-on-old-software-is-dangerous.yml