表达式在哪儿求值
Ansible 里成对花括号包起来的内容都是 Jinja2 表达式,它会出现在任务参数、模板文件与变量定义中,求值结果可以是字符串、数字、布尔、列表或字典。基础构件只有几样:引用变量与嵌套键、条件表达式、管道过滤器、迭代与条件语句。最需要注意的是求值发生在控制端:表达式先被渲染成文本,再传给目标机执行,远端 shell 的变量不会被提前展开。
基本信息
| 三种分隔符 | 双花括号取值、花括号加百分号写语句、花括号加井号写注释 |
|---|---|
| 常用写法 | 变量引用、字典按键取值、默认值过滤器、条件表达式 |
| 求值位置 | 控制端,渲染结果再下发给目标机 |
| 类型保留 | 表达式结果保留原类型,除非显式转换 |
典型使用场景
- 模板文件生成配置:变量引用配合条件块,按环境产出不同内容
- 任务参数拼接路径与值:用表达式而不是字符串拼接,避免引号问题
- 变量定义里按环境取不同值:用条件表达式一次写清分支
- 遍历主机或列表生成多行内容:用迭代语句产出成组配置
- 需要把内容整段原样下发:注意转义与求值层次,别让远端符号被提前替换
基础写法
基础写法
# templates/app.conf.j2
listen {{ app_port | default(8080) }}; # 变量缺失时用默认值
{% for host in groups['web'] %} # 迭代分组内主机
server {{ host }}:{{ hostvars[host].app_port }}; # 跨主机取值
{% endfor %}
{% if enable_tls %} # 条件块决定是否输出
ssl on;
{% endif %}写法与注意
| 写法 | 含义 | 注意 |
|---|---|---|
| 双花括号取值 | 计算表达式并输出 | 结果保留类型,不会强制转字符串 |
| 默认值过滤器 | 变量未定义时用替代值 | 会掩盖变量名拼写错误 |
| 迭代语句 | 按列表重复输出文本 | 注意空白与换行控制 |
| 条件语句 | 按布尔值决定是否输出 | 判断前先确认类型 |
结果本身是字符串时,表达式外面加引号会把引号一起写进结果;只有需要输出字面字符串(含空格或特殊字符)时才在表达式外补引号。
表达式在控制端完成求值,不会被目标机再解释一次。想让远端脚本自己展开某个符号,必须做好转义或改成运行时再取值,两层混淆会把远端变量提前替换成控制端的值。
调试的基本功
模板出问题先看渲染结果而不是猜语法:把表达式单独放进调试任务打印出来,确认取值与类型;再看上下文里有没有同名变量把它覆盖掉。表达式越长越容易出错,拆成中间变量再引用,既能复用也便于逐步定位。