0

0

Linux Ansible 高级用法与模块

冷漠man

冷漠man

发布时间:2026-02-20 05:41:33

|

348人浏览过

|

来源于php中文网

原创

优先选 ansible.builtin.command(除非需管道/重定向/变量展开);command 更安全轻量,shell 易出错且有子shell陷阱。

linux ansible 高级用法与模块

ansible.builtin.shell 和 ansible.builtin.command 选哪个?

shellcommand 看似都能执行命令,但底层行为完全不同。前者调用 /bin/sh(或指定 shell),支持管道、重定向、变量展开;后者绕过 shell,直接 execve,不解析 $PATH、不支持 |&&

常见错误现象:用 commandls /tmp | grep log 报错 unrecognized arguments: |;或者用 shell 执行 cd /opt && ./deploy.sh,结果发现 cd 不生效——因为每条 shell 任务都是独立子 shell。

使用场景:

  • command:调用绝对路径二进制(如 /usr/bin/touch)、避免 shell 注入、需要确定性执行环境
  • shell:必须用管道/重定向/环境变量、依赖当前用户 shell 配置(比如 ~/.bashrc 里的 alias)

性能影响:command 更轻量,无 shell 解析开销;shell 多一层进程 fork,且可能引入意外的 shell 行为(比如 glob 展开)。

- command: /bin/echo "hello"
- shell: echo $HOME | tr 'a-z' 'A-Z'

如何让 loop 变量在 when 条件里安全使用?

Ansible 的 loop(或旧式 with_items)和 when 组合时,容易踩「变量未定义」或「类型不匹配」的坑。比如遍历一个字典列表,但某一项缺 key,when: item.port == 8080 就会报 error while evaluating conditional

根本原因是 Ansible 默认开启 jinja2_strict_undefined,访问不存在的 key 直接失败。

解决办法只有两个:

  • item.port | default(80) 显式兜底
  • 改用 item.get('port', 80)(推荐,更接近 Python 习惯)

别写 when: item.port is defined and item.port == 8080——它不能防止 item 本身是 None 或字符串。

另外注意:loop 中的 item 类型完全取决于你传进去的数据,不是所有情况都是 dict。如果源是 [1, 2, "abc"]item.port 永远是错的。

- name: restart only nginx services with port 80
  service:
    name: "{{ item.name }}"
    state: restarted
  loop: "{{ services }}"
  when: item.port | default(80) == 80

ansible.builtin.include_tasks vs. ansible.builtin.import_tasks 怎么选?

关键区别就一条:import_tasks 是静态包含,在 playbook 解析阶段就加载并展开全部任务;include_tasks 是动态包含,运行时才读取文件、才决定是否执行(支持 whenloop 控制)。

开源电子商务系统(网店) iWebShop
开源电子商务系统(网店) iWebShop

iWebShop基于iWebSI框架开发,在获得iWebSI技术平台库支持的条件下,iWebShop可以轻松满足用户量级百万至千万级的大型电子商务网站的性能要求。站点的集群与分布式技术(分布式计算与存储/高可用性/负载均衡)被屏蔽在SI 平台之内,基于iWebShop并且按照SI平台库扩展规范开发的新增功能模块,也将同时获得这种超级计算与处理的能力。作为开源的LAMP电子商务系统,iWebShop

下载

常见错误现象:

  • include_tasks 的文件里用了 loop,但外层 task 写了 when: false,结果文件还是被读取了(只是任务不执行)——这没问题;
  • 但反过来,用 import_tasks + when,条件不满足时整个 import 会被跳过,连语法检查都做不了,容易掩盖 YAML 错误。

使用场景:

  • import_tasks:通用初始化任务(如共用的权限设置)、需要被 tags--start-at-task 定位的稳定流程
  • include_tasks:根据变量动态加载逻辑(如不同 OS 加载不同包安装任务)、配合 loop 分批执行、调试时想临时跳过某段

兼容性注意:Ansible 2.12+ 已弃用 include(不带 _tasks 后缀),只保留这两个明确语义的模块。

为什么 register 的变量在后续 play 里用不了?

Ansible 的变量作用域默认是「play 级」,register 存的变量只在当前 play 内有效。跨 play 访问会得到 UndefinedVariable

这不是 bug,是设计使然:避免隐式依赖、提升可读性、防止状态污染。

如果你真需要跨 play 共享,只有两个合规方式:

  • set_fact + cacheable: true(需启用 fact cache,如 fact_caching: jsonfile
  • 把值写到文件(copylineinfile),下个 play 再读(适合简单字符串)

别用 hostvars[inventory_hostname] 强取——它只对当前 play 的 hostvars 有效,跨 play 依然空。

还有一个易忽略点:register 的变量名如果含破折号(如 my-result),Jinja2 里必须写成 hostvars[inventory_hostname]['my-result'],不能点号访问。

- name: get uptime
  command: uptime
  register: uptime_result
<ul><li><p>name: use it in same play — OK
debug: var=uptime_result.stdout</p></li><li><p>name: use it in next play — FAIL unless set_fact or cache
debug: var=uptime_result</p>

复杂点在于:Ansible 不提供“全局变量”机制,所有跨 play 数据传递都得显式落地。很多人卡在这儿,不是不会写,是没意识到这是故意的设计约束。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

103

2023.09.25

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

371

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

340

2023.10.25

全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

85

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

101

2025.09.18

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

574

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

217

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1555

2023.10.24

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

660

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 9.4万人学习

Git 教程
Git 教程

共21课时 | 3.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号