刚学Ansible的新手,肯定都懵过:command和shell模块,不都是远程执行命令吗?为啥有时候用command报错,换shell就好使?
核心就1句大白话:执行命令时,要不要找"中间人"(shell解释器)帮忙。不用记复杂概念,今天用最简单的话+实操例子,讲清两者区别,新手看完就知道该用哪个。
一、先搞懂:两者执行方式不一样
不用管底层原理,记住两个类比,瞬间明白:
1. command模块:直接"喊"程序干活,不找中间人
用command执行命令,会直接调用目标机器上的程序,不经过任何"翻译"(shell解释器,比如bash)。
例子:用command执行ls /home,Ansible直接找到系统里的ls程序,让它查/home目录,一步到位。
特点:快、简单,但笨------不支持任何"高级操作"(比如管道、重定向)。
2. shell模块:先找中间人,再让中间人"喊"程序干活
用shell执行命令,会先启动目标机器的默认"中间人"(默认是/bin/sh),再让这个中间人去调用程序、执行命令。
还是执行ls /home,用shell的话,流程是:Ansible启动中间人→中间人喊ls程序→执行命令。
特点:灵活、能干------支持所有高级操作,但比command慢一点,还有点安全风险。
二、核心区别:一张表看清
不用死记,遇到分不清的情况,对照这张表找答案,一目了然:
| 对比维度 | command模块 | shell模块 |
|---|---|---|
| 要不要中间人(shell) | 不要,直接调用程序 | 要,默认用/bin/sh |
| 支持管道(|) | 不支持(新手记死) | 支持 |
| 支持重定向(>、>>) | 不支持(新手记死) | 支持 |
| 支持环境变量($HOME等) | 不支持(直接输出$HOME) | 支持(能输出真实路径) |
| 安全性 | 高(不容易出问题) | 较低(有安全风险) |
| Ansible默认用哪个 | 是(不指定模块就用它) | 否(要手动指定-m shell) |
三、实战示例:新手最常遇到的3种情况
光看表不够,结合例子练1次,以后再也不踩坑!
场景1:简单命令(比如重启服务)------优先用command
像重启nginx、查看文件,这种简单操作,两者都能用,但优先选command(快、安全)。
yaml
# 推荐:用command重启nginx
- name: restart nginx with command
command: systemctl restart nginx
# 能用但没必要:用shell重启nginx
- name: restart nginx with shell
shell: systemctl restart nginx
场景2:用管道、重定向------只能用shell
新手最容易踩坑的地方!只要命令里有|、>、>>,用command必报错,换shell就好。
yaml
# 错误:command不能用管道
- name: 查看java进程(报错)
command: ps aux | grep java
# 正确:用shell执行管道命令
- name: 查看java进程(正常)
shell: ps aux | grep java
# 正确:用shell重定向写入文件
- name: 写内容到文件
shell: echo "Sheffield" > /tmp/test.txt
场景3:用环境变量(比如$HOME)------只能用shell
想调用$HOME、$PATH这种环境变量,command不识别,必须用shell。
bash
# 正确:用shell查看家目录
- name: 查看家目录
shell: echo $HOME # 会输出/root(管理员用户)
# 错误:command查看家目录(只会输出$HOME)
- name: 查看家目录(报错效果)
command: echo $HOME
四、安全提醒
shell虽然好用,但如果命令里有用户输入、变量,容易被恶意攻击(比如删文件)。
简单说:能不用shell就不用,必须用的时候,别随便放用户输入的内容。
五、新手速记:3句话搞定所有场景
- 简单命令(不涉及|、>、$):优先用command(默认、安全、快);
- 用到管道、重定向、环境变量:只能用shell;
- 命令里有用户输入、变量:优先用command,避免风险。
常见误区(避坑!)
-
误区:shell比command强,所有场景都用shell
------错!非必要不用,费资源还不安全;
-
误区:两者用法不一样
------错!常用参数(比如切换目录),用法完全相同;
-
误区:command用不了的,shell也用不了
------错!只要有shell解释器,shell都能搞定。
其实新手不用想太复杂,记住"简单用command,复杂用shell",就能应对99%的场景。练两次实操,很快就能分清~