Ответ
Оба модуля выполняют команды на целевых хостах, но принципиально различаются по способу исполнения и безопасности.
Модуль command выполняет команду напрямую, без оболочки (shell). Это означает:
- Нет раскрытия переменных окружения (
$PATH,$HOME). - Нет обработки shell-операторов: перенаправления (
>,>>), пайпов (|), логических операторов (&&,||), подстановки (*). - Более безопасно, так как исключает риски инъекций через shell-интерпретацию.
Модуль shell выполняет команду через оболочку хоста (по умолчанию /bin/sh). Он поддерживает все возможности shell.
Сравнение на примере:
- name: Попытка использовать перенаправление с command (НЕ СРАБОТАЕТ)
ansible.builtin.command: echo "data" > /tmp/file.txt
# Модуль command попытается найти программу с именем 'echo "data" > /tmp/file.txt' и завершится ошибкой.
- name: Использование shell для перенаправления (РАБОТАЕТ)
ansible.builtin.shell: echo "data" > /tmp/file.txt
# Команда будет выполнена через /bin/sh, который обработает оператор '>'.
- name: Безопасное использование command с модулем copy
ansible.builtin.copy:
content: "data"
dest: /tmp/file.txt
# Правильный идиоматичный способ в Ansible — использовать специализированный модуль.
Рекомендации по использованию (из практики):
- Всегда предпочитайте
command, если команда простая и не требует shell. Это безопаснее и предсказуемее. - Используйте
shellтолько когда необходимы специфические возможности оболочки (пайпы, перенаправление, циклы в одной строке). - Для сложных операций используйте специализированные модули Ansible (
copy,lineinfile,template,systemd). Они идиоматичны, обеспечивают идемпотентность и дают лучшую обратную связь. - При использовании
shellявно задавайте исполняемую оболочку, если нужна конкретная (например, bash-специфичный синтаксис):- name: Run command with bash ansible.builtin.shell: cmd: echo "Home is $HOME" executable: /bin/bash