如何强制 Ansible 实时显示命令输出,以便您可以对其做出反应,尤其是在它提示用户的情况下?
我正在尝试编写一些步骤来登录 Cloudflare、设置隧道,而 Ansible 隐藏所有输出的默认行为使这变得不可能。
我的剧本看起来像:
tasks:
- name: Check if Cloudflare cert exists
tags: cloudflare
ansible.builtin.stat:
path: /home/myuser/.cloudflared/cert.pem
register: cloudflare_cert
- name: Log in to Cloudflare if cert.pem does not exist
tags: cloudflare
ansible.builtin.shell:
cmd: cloudflared login | tee /dev/tty
when: not cloudflare_cert.stat.exists
changed_when: true
environment:
PYTHONUNBUFFERED: 1
但是 Ansible 在执行
cloudflared login
时无限期挂起,因为它正在阻塞,等待我访问我看不到的 URL。无缓冲标志和 tee /dev/tty
已适用于其他命令,例如 rsync,以获取实时显示的输出,但由于某种原因,它不适用于“cloudflared 登录”。这是为什么?
我也尝试过:
- name: Log in to Cloudflare if cert.pem does not exist
tags: cloudflare
ansible.builtin.command: cloudflared login
when: not cloudflare_cert.stat.exists
changed_when: true
environment:
PYTHONUNBUFFERED: 1
和
- name: Log in to Cloudflare if cert.pem does not exist
tags: cloudflare
ansible.builtin.shell:
cmd: script -q -c "cloudflared login" /dev/null
when: not cloudflare_cert.stat.exists
changed_when: true
environment:
PYTHONUNBUFFERED: 1
但两者都不起作用。我错过了什么?
您的帖子包含几个不同的问题,其中一个是关于实时或流日志的,所以让我们先回答这个问题。
“无缓冲标志和
tee /dev/tty
已起作用”,但仅限于localhost
!
这是一个最小的示例剧本
---
- hosts: localhost
become: false
gather_facts: false
tasks:
- shell:
cmd: for i in {1..5}; do echo $i; done | tee /dev/tty
register: result
environment:
PYTHONUNBUFFERED: 1
- debug:
var: result
将产生
的输出PLAY [localhost] *****************************************
1
2
3
4
5
TASK [shell] *********************************************
changed: [localhost]
TASK [debug] *********************************************
ok: [localhost] =>
result:
changed: true
cmd: for i in {1..5}; do echo $i; done | tee /dev/tty
delta: '0:00:00.006917'
end: '2024-10-16 09:00:00.645649'
failed: false
msg: ''
rc: 0
start: '2024-10-16 09:00:00.638732'
stderr: ''
stderr_lines: []
stdout: |-
1
2
3
4
5
stdout_lines:
- '1'
- '2'
- '3'
- '4'
- '5'
在远程受管节点 (
test
) 上运行它可以也不能。
PLAY [test] **********************************************
TASK [shell] *********************************************
changed: [test.example.com]
TASK [debug] *********************************************
ok: [test.example.com] =>
result:
changed: true
cmd: for i in {1..5}; do echo $i; done | tee /dev/tty
delta: '0:00:00.008797'
end: '2024-10-16 09:05:00.605952'
failed: false
msg: ''
rc: 0
start: '2024-10-16 09:05:00.597155'
stderr: ''
stderr_lines: []
stdout: |-
1
2
3
4
5
stdout_lines:
- '1'
- '2'
- '3'
- '4'
- '5'
“Ansible默认隐藏所有输出的行为”,这里要注意的是根据模块简介和返回值
Ansible 通常在远程受管节点上执行每个模块,并收集返回值。
和
Ansible 模块通常返回一个可以注册到变量中的数据结构...
由于分布式系统的性质和行为,这种实时输出并未实现。您可以进一步回答“如何在运行 Ansible 播放时获取其输出?”的答案,并按照其中的所有链接进行操作。
第二个问题“这样你就可以对其做出反应,特别是当它提示用户时?”是如何对输出做出反应,与会话交互或回答输入问题。由于分布式系统的性质和行为,这种方法也没有实现。正如评论中已经提到的,它会让您使用 expect
模块 – 执行命令并响应提示
、模板配置文件、分发或提供答案或响应文件。