Ansible实战:如何正确选择 command 和shell模块?

在使用Ansible进行自动化运维时,commandshell 模块是我们执行命令的好帮手。虽然它们看起来很相似,但在功能特性和适用场景上其实有着明显的不同。正确选择合适的模块不仅能够提高任务的效率,还能帮助我们规避一些潜在的风险。在这篇文章中,我们将深入探讨 commandshell模块之间的差异,并通过一些高级案例来展示如何恰当地选择和使用它们。

两者模块的区别

特性 commad模块 shell模块
解析方式 不使用shell解析 使用完整的shell 解析
支持特性 不支持管道 重定向、管道等shell 功能
安全性 更安全,防止命令注入 存在命令注入风险,需要严格验证输入
适用场景 执行简单命令,如ls、mkdir等 执行复杂命令或需要shell功能的场景

常见场景及模块选择

执行简单命令

适合场景:执行单一命令,无需复杂的shell功能。
推荐模块command

示例:在远程主机上创建目录

bash 复制代码
ansible -m  node2 command -a 'mkdir -p /tmp/node1'

以下述命令是通过ad-hoc方式创建,简单的命令用这种方式很方便。执行成功如所示:

bash 复制代码
root@ansible:~# ansible   node2 -m  command -a 'mkdir -p /tmp/node2'
192.168.31.102 | CHANGED | rc=0 >>
root@ansible:~# ansible   node2 -m  command -a 'ls  /tmp'
192.168.31.102 | CHANGED | rc=0 >>
....
node2
.....

以下方式通过剧本方式创建:

yaml 复制代码
---
- name: 使用command模块创建目录
  hosts: node2
  gather_facts: yes
  tasks:
    - name: 使用command模块创建目录
      command: mkdir -p /tmp/mydir

通过ansible-playbook执行成功,输出如下图所示:

使用管道或重定向

适合场景:需要使用shell特性(如管道、重定向)处理复杂逻辑。
推荐模块shell

示例 :统计日志文件中包含 error 的行数

bash 复制代码
root@ansible:~/test# ansible node2  -m shell -a 'grep 'error' /var/log/dmesg | wc -l'
192.168.31.102 | CHANGED | rc=0 >>
0
yaml 复制代码
---
- name: 使用shell模块统计日志中的错误行数
  hosts: node2
  tasks:
    - name: 使用shell模块统计日志中的错误行数
      shell: grep 'error' /var/log/messages | wc -l
      register: error_count
    - name: 打印错误行数
      ansible.builtin.debug:
        msg: "日志中包含的错误行数为:{{ error_count.stdout }}"

通过ansible-playbook执行成功,输出如下图所示:

动态变量替换

适合场景:需要解析变量或动态生成命令。
推荐模块shell

示例:获取当前主机名并打印

yaml 复制代码
---
- name: 获取主机名
  hosts: node2
  tasks:
    - name: 获取主机名
      ansible.builtin.shell: hostname
      register: hostname_output
    
    - name: 打印主机名
      ansible.builtin.debug:
        msg: "当前主机名为:{{ hostname_output.stdout }}"

定期备份数据库

需求:通过cron任务,每日备份数据库并压缩备份文件。

  • 使用 shell 模块
bash 复制代码
ansible node2 -m shell -a \
"mysqldump -u root -p'password' mydatabase | gzip > /backups/mydatabase_$(date +'%Y%m%d').sql.gz"

说明shell 模块支持日期命令 $(date),可以动态生成文件名。

清理大文件

需求 :删除 /var/log/ 目录中超过 100M 的文件。

  • 使用 shell 模块
bash 复制代码
ansible node2 -m shell -a "find /var/log/ -type f -size +100M -exec rm -f {} \;"

说明find 命令需要结合-exec,只能用shell 模块完成。

监控服务状态

需求 :检查远程主机上的Nginx服务是否正在运行。

  • 使用 command 模块
bash 复制代码
ansible node2 -m command  -a "systemctl is-active nginx"

总结

  1. 优先使用command模块
    如果命令可以通过 command 模块实现,优先选择它以确保安全性。
  2. 适时使用shell模块
    当任务需要使用管道、重定向、环境变量或命令替换时,选择shell模块。

通过合理选择和使用commandshell 模块,可以高效完成复杂任务,同时确保系统安全性。希望本文的解析与案例能帮助你在Ansible自动化管理中更加得心应手!

推荐阅读



相关推荐
chlk1236 小时前
Linux文件权限完全图解:读懂 ls -l 和 chmod 755 背后的秘密
linux·操作系统
舒一笑7 小时前
Ubuntu系统安装CodeX出现问题
linux·后端
改一下配置文件7 小时前
Ubuntu24.04安装NVIDIA驱动完整指南(含Secure Boot解决方案)
linux
深紫色的三北六号17 小时前
Linux 服务器磁盘扩容与目录迁移:rsync + bind mount 实现服务无感迁移(无需修改配置)
linux·扩容·服务迁移
SudosuBash21 小时前
[CS:APP 3e] 关于对 第 12 章 读/写者的一点思考和题解 (作业 12.19,12.20,12.21)
linux·并发·操作系统(os)
哈基咪怎么可能是AI1 天前
为什么我就想要「线性历史 + Signed Commits」GitHub 却把我当猴耍 🤬🎙️
linux·github
十日十行2 天前
Linux和window共享文件夹
linux
Sinclair2 天前
简单几步,安卓手机秒变服务器,安装 CMS 程序
android·服务器
木心月转码ing2 天前
WSL+Cpp开发环境配置
linux
Rockbean3 天前
用40行代码搭建自己的无服务器OCR
服务器·python·deepseek