Ansible教程:command模块 作者:马育民 • 2026-09-20 22:31 • 阅读:10001 # 介绍 **command 是 Ansible 默认模块**,在远程主机执行简单命令;**命令不会经过 shell 解析**,管道、重定向、`&`、`;`、通配符、shell变量都无法生效。 模块全名:`ansible.builtin.command`,ad-hoc 命令可以省略 `-m command`。 # 原理 把命令参数直接传给远程主机的系统调用(exec)执行,**不启动 shell**。 ### 优点 更安全、解析简单、不容易出现引号转义问题 ### 限制 不支持 shell 语法 `| > < & ; * $var`;需要这些语法请改用 `shell` 模块 # 常用参数 | 参数 | 说明 | |---|---| | `cmd` | 要执行的命令,playbook 推荐使用 `cmd:` 写法替代 free-form | | `chdir` | 执行命令前,先切换到远程主机指定目录(cd) | | `creates` | 指定一个文件路径:**文件存在 → 跳过本次命令;文件不存在 → 执行**(用来实现简易幂等) | | `removes` | 指定一个文件路径:**文件存在 → 执行;文件不存在 → 跳过** | | `stdin` | 把指定字符串作为命令标准输入传给进程 | | `warn` | bool,是否开启 Ansible 内置命令警告,默认 true | > free_form:不是一个参数名,代表直接写命令字符串,ad-hoc 最常用。 # Ad-hoc 临时命令示例 使用 Ad-hoc 临时命令,默认使用 **command模块**,省略 `-m command` 参数 ### 1. 查看负载 ##### 使用 hosts 文件 ```bash ansible all -a "uptime" ``` **解释:** `-a` 后面跟命令 ##### 自定义 inventory 文件 ``` ansible all -a "uptime" -i ansible_client.ini ``` ### 2. chdir:先cd到/etc,再执行cat centos-release ##### Ubuntu系统,自定义 inventory 文件 ``` ansible all -a "chdir=/etc cat os-release" -i ansible_client.ini ``` ##### centos系统,使用 hosts 文件 ``` ansible all -a "chdir=/etc cat centos-release" ``` ### 3. creates:/tmp/ok.txt不存在才执行touch;文件存在则跳过 ``` ansible all -a "chdir=/tmp creates=/tmp/ok.txt touch ok.txt" ``` ### 4. removes:/tmp/ok.txt存在才删除 ``` ansible all -a "chdir=/tmp removes=/tmp/ok.txt rm ok.txt" ``` # Playbook 写法示例 ```yaml - name: command模块演示 hosts: all tasks: - name: 查看当前目录 ansible.builtin.command: pwd args: chdir: /tmp - name: 文件不存在才创建 command: touch test.txt args: chdir: /tmp creates: /tmp/test.txt - name: 文件存在才删除 command: rm test.txt args: chdir: /tmp removes: /tmp/test.txt ``` # 限制(高频踩坑点) 1. **不支持管道 `|`、重定向 `> <`、分号 `;`、后台 `&`、通配符 `*`、shell变量 `$HOME`** ```yaml # ❌ command中无效,不会报错但不会按shell预期执行 command: echo hello > /tmp/1.txt command: ps aux | grep nginx ``` > 上面这些场景必须使用 `shell` 模块。 2. **command 本身不具备幂等性** `creates / removes` 只是简单的文件判断,不是真正幂等。多次执行无文件判断的命令(如`echo`),每次都会返回 `changed`。 > Ansible 最佳实践:优先使用原生模块(file、copy、service),尽量少用 command/shell。 # command vs shell 模块对比 | | command | shell | |---|---|---| | 是否经过shell | ❌ 否,直接exec | ✅ 是,调用/bin/sh | | 管道/重定向 | ❌ 不支持 | ✅ 支持 | | shell变量$var | ❌ 不解析 | ✅ 支持 | | 通配符* | ❌ 不支持 | ✅ 支持 | | 安全性 | 更高,无shell注入风险 | 较低,需要小心引号注入 | | 适用场景 | 简单独立命令 | 需要shell语法、脚本执行 | ### 什么时候选 command / shell - ✅ **command**:简单命令,不需要管道、重定向,如 `ls`、`pwd`、`hostname`、`tar xf xxx.tar` - ✅ **shell**:需要 `| > ; &`、shell变量、通配符,执行bash脚本 原文出处:/show_1GW45HljLErf.html