在 Ansible playbook 中使用 register 捕获命令输出并进行条件判断,核心是在任务中定义 register 变量保存结果,随后在后续任务的 when 子句中引用该变量的属性(如 rc、stdout)。适用场景包括根据命令返回值决定是否执行后续操作,风险边界在于需处理命令失败导致的任务中断。
先说结论:register 将任务执行结果存入变量,when 子句根据变量属性控制后续任务执行。
- 适合:需要根据 shell 命令返回值或输出内容决定流程的场景
- 先看:注册变量的结构包含 rc、stdout、stderr 等关键字段
- 建议:命令可能失败时需配合 ignore_errors 防止 playbook 提前终止
命令速用版
- name: Check service status
command: systemctl is-active nginx
register: service_status
ignore_errors: yes
- name: Start service if stopped
command: systemctl start nginx
when: service_status.rc != 0为什么会这样
Ansible 任务默认独立执行,register 机制实现任务间数据传递。
Ansible 每个任务通常独立运行,前一个任务的输出不会自动传递给后一个任务。register 关键字将当前任务的执行结果字典保存到指定变量名中,后续任务可以通过 when 条件语句读取该变量的字段,如返回码 rc 或标准输出 stdout,从而实现基于执行结果的逻辑分支。
分步处理
第一步:在需要捕获输出的任务中添加 register 字段。
定义任务时指定变量名,例如 register: cmd_result。该变量将包含命令的所有执行细节,包括返回码、输出内容和执行状态。
第二步:在后续任务中使用 when 子句引用注册变量。
编写 when 条件,例如 when: cmd_result.rc == 0。支持比较运算符和逻辑判断,如 in 操作符检查 stdout 内容。
第三步:处理可能的命令失败情况。
如果命令可能返回非零退出码,需在第一个任务添加 ignore_errors: yes,否则 playbook 会在该任务失败时停止,后续条件判断无法执行。
怎么验证是否生效
使用 debug 模块打印注册变量内容确认结构。
在 playbook 中添加 debug 任务,var: cmd_result。运行 playbook 时观察输出,确认 rc 和 stdout 字段是否符合预期。也可使用 ansible-playbook `--check` 模式测试逻辑而不实际执行变更。
常见坑
忽略命令失败导致 playbook 中断是最高频错误。
若命令执行失败且未设置 ignore_errors,Ansible 会终止当前 play,后续依赖 register 变量的任务不会运行。此外,register 变量作用域限于当前 play,跨 play 使用需特殊处理。条件判断时需注意 rc 是整数,stdout 是字符串,类型匹配错误会导致条件永远为假。
常见问题
register 变量中 rc 和 failed 有什么区别
rc 是命令退出码,failed 是 Ansible 任务状态标记。
rc 来自被执行命令的返回值,0 通常表示成功。failed 是 Ansible 根据 rc 和非零返回判断的任务状态,命令失败时 failed 为 true。条件判断常用 rc 精确控制,或用 failed 判断任务是否异常。
如何判断命令输出中是否包含特定字符串
使用 in 操作符检查 stdout 字段。
写法为 when: "'keyword' in result.stdout"。注意 stdout 是字符串,需确保关键字确实存在于输出文本中,大小写敏感。
register 变量能在多个 play 之间共享吗
默认不能,变量作用域限制在当前 play 内。
不同 play 之间 register 变量不互通。若需跨 play 传递数据,需使用 set_fact 将变量设为 host_fact 或通过临时文件传递。
参考来源
- Ansible Documentation, Playbooks: Registering variables, https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_register.html
- Ansible Documentation, Playbooks: Conditionals, https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_conditionals.html