
Ansible 的 shell 模块天然支持管道(|)、重定向(>、>>)和命令组合,因此可以直接在远程主机上执行含管道的复杂命令链,实现部署过程中的实时结果过滤与解析。
为什么必须用 shell 模块而非 command 模块
command 模块为安全设计,默认不经过 shell 解析器,会直接拒绝 |、&&、$()、重定向等语法;而 shell 模块调用的是远程主机的 /bin/sh(通常是 bash),能完整解析并执行带管道的复合命令。
- 若使用
command模块写ps aux | grep nginx,会报错:unrecognized arguments: | - 用
shell模块则可正常运行:ansible web -m shell -a "ps aux | grep nginx | grep -v grep | awk '{print \$2,\$11}'"
典型部署后二次过滤场景示例
常见于服务启动后验证状态、提取关键字段、去重统计或条件判断。例如:
- 确认 Nginx 进程是否以指定用户运行,并只取 PID 和二进制路径:
- 检查已安装 Python 包中含
requests的版本,并排除警告行:
- 从部署日志中提取最后 5 行成功标记,并统计出现次数:
结合 chdir 与多级管道提升可靠性
实际部署常需先切换目录再执行命令链。利用 chdir 参数可避免路径错误,且不影响管道逻辑:
- 进入应用目录后,查看当前 Git 分支 + 最近 3 条提交摘要:
注意:上面命令中 && 和 | 都在 shell 模块内被解析,无需额外封装脚本。
将管道结果用于后续条件判断(playbook 中)
在 playbook 中,可将 shell 模块输出注册为变量,再用 when 或 assert 做断言:
- name: 获取活跃容器数量
shell: docker ps --format '{{.ID}}' | wc -l
register: container_count
<ul><li>name: 确保至少运行 2 个容器
assert:
that: container_count.stdout | int >= 2
msg: "Expected at least 2 containers, got {{ container_count.stdout }}"
这里 docker ps ... | wc -l 是完整的管道表达式,由 shell 模块执行后,stdout 可被 Jinja2 安全转换为整数参与判断。


















