Проверьте только, присутствует ли строка в файле (возможно)
В ansible мне нужно проверить, присутствует ли конкретная строка в файле или нет. По сути, мне нужно преобразовать следующую команду в ANSIBLE задачу. Моя цель - только проверить.
grep -Fxq "127.0.0.1" /tmp/my.conf
Ответы
Ответ 1
- name: Check whether /tmp/my.conf contains "127.0.0.1"
command: grep -Fxq "127.0.0.1" /tmp/my.conf
register: checkmyconf
check_mode: no
ignore_errors: yes
changed_when: no
- name: Greet the world if /tmp/my.conf contains "127.0.0.1"
debug: msg="Hello, world!"
when: checkmyconf.rc == 0
Обновление 2017-08-28: Предыдущие версии Ansible должны использовать always_run: yes
вместо check_mode: no
.
Ответ 2
Используйте check_mode, зарегистрируйтесь и failed_when в концерте. Это не выполнит задачу, если модуль lineinfile внесет какие-либо изменения в проверяемый файл. Check_mode гарантирует, что ничего не изменится, даже если это будет иначе.
- name: "Ensure /tmp/my.conf contains '127.0.0.1'"
lineinfile:
name: /tmp/my.conf
line: "127.0.0.1"
state: present
check_mode: yes
register: conf
failed_when: (conf is changed) or (conf is failed)
Ответ 3
При принятом решении, даже если вы игнорируете ошибки, вы по-прежнему будете получать уродливые красные ошибки при первой задаче, если нет совпадения:
TASK: [Check whether /tmp/my.conf contains "127.0.0.1"] ***********************
failed: [localhost] => {"changed": false, "cmd": "grep -Fxq "127.0.0.1" /tmp/my.conf", "delta": "0:00:00.018709", "end": "2015-09-27 17:46:18.252024", "rc": 1, "start": "2015-09-27 17:46:18.233315", "stdout_lines": [], "warnings": []}
...ignoring
Если вам нужен менее подробный вывод, вы можете использовать awk
вместо grep
. awk
не будет возвращать ошибку при несоответствии, что означает, что первая задача проверки ниже будет ошибкой независимо от совпадения или несоответствия:
- name: Check whether /tmp/my.conf contains "127.0.0.1"
command: awk /^127.0.0.1$/ /tmp/my.conf
register: checkmyconf
changed_when: False
- name: Greet the world if /tmp/my.conf contains "127.0.0.1"
debug: msg="Hello, world!"
when: checkmyconf.stdout | match("127.0.0.1")
Обратите внимание, что моя вторая задача использует фильтр соответствия, поскольку awk возвращает совпадающую строку, если находит совпадение.
Вышеуказанная альтернатива будет выдавать следующий результат независимо от того, имеет ли задача проверки совпадение или нет:
TASK: [Check whether /tmp/my.conf contains "127.0.0.1"] ***********************
ok: [localhost]
IMHO это лучший подход, так как вы не будете игнорировать другие ошибки в своей первой задаче (например, если указанный файл не существует).
Ответ 4
Используйте команду ansible lineinfile, но эта команда будет обновлять файл с помощью строки, если она не существует.
- lineinfile: dest=/tmp/my.conf line='127.0.0.1' state=present
Ответ 5
Пользователь robo regexp
& Метод absent
довольно чистый, поэтому я привел его здесь для простоты использования и добавил улучшения из комментариев @assylias и @Olivier:
- name: Ensure /tmp/my.conf contains 127.0.0.1
lineinfile:
path: /tmp/my.conf
regexp: '^127\.0\.0\.1.*whatever'
state: absent
check_mode: yes
changed_when: false
register: out
- debug:
msg: "Yes, line exists."
when: out.found
- debug:
msg: "Line does NOT exist."
when: not out.found
Ответ 6
Другой способ - использовать "модуль замены", затем "lineinfile module".
Алго закрывается для того, что используется, когда вы хотите изменить значения двух переменных.
- Сначала используйте "модуль замены", чтобы определить, находится ли строка, которую вы ищете, и меняйте ее с чем-то другим. (Подобно той же строке + что-то в конце).
- Тогда, если "replace" - true, это означает, что ваша строка здесь, а затем замените новую строку на конкретную, с новой строкой.
- Еще одна строка, которую вы ищете, здесь отсутствует.
Пример:
# Vars
- name: Set parameters
set_fact:
newline : "hello, i love ansible"
lineSearched : "hello"
lineModified : "hello you"
# Tasks
- name: Try to replace the line
replace:
dest : /dir/file
replace : '{{ lineModified }} '
regexp : '{{ lineSearched }}$'
backup : yes
register : checkIfLineIsHere
- name: Line is here, change it
lineinfile:
state : present
dest : /dir/file
line : '{{ newline }}'
regexp : '{{ lineModified }}$'
when: checkIfLineIsHere.changed
- Если файл содержит "привет" , он станет "здравствуйте", а затем "привет, я люблю незаметный" в конце.
- Если содержимое файла не содержит "привет" , файл не изменяется.
С той же идеей вы можете сделать что-то, если здесь находится строка:
# Vars
- name: Set parameters
set_fact:
newline : "hello, i love ansible"
lineSearched : "hello"
lineModified : "hello you"
# Tasks
- name: Try to replace the line
replace:
dest : /dir/file
replace : '{{ lineModified }} '
regexp : '{{ lineSearched }}$'
backup : yes
register : checkIfLineIsHere
# If the line is here, I want to add something.
- name: If line is here, do something
lineinfile:
state : present
dest : /dir/file
line : '{{ newline }}'
regexp : ''
insertafter: EOF
when: checkIfLineIsHere.changed
# But I still want this line in the file, Then restore it
- name: Restore the searched line.
lineinfile:
state : present
dest : /dir/file
line : '{{ lineSearched }}'
regexp : '{{ lineModified }}$'
when: checkIfLineIsHere.changed
- Если файл содержит "привет" , строка все равно будет содержать "привет" и "привет, я люблю возможность" в конце.
- Если содержимое файла не содержит "привет" , файл не изменяется.
Ответ 7
Вы можете использовать файловый плагин для этого сценария.
Чтобы установить факт, который вы можете использовать в других задачах... это работает.
- name: Check whether /tmp/my.conf contains "127.0.0.1"
set_fact:
myconf: "{{ lookup('file', '/tmp/my.conf') }}"
ignore_errors: yes
- name: Greet the world if /tmp/my.conf contains "127.0.0.1"
debug: msg="Hello, world!"
when: "'127.0.0.1' in myconf"
Чтобы проверить содержимое файла как условие задачи... это должно работать.
- name: Greet the world if /tmp/my.conf contains "127.0.0.1"
debug: msg="Hello, world!"
when: "'127.0.0.1' in lookup('file', '/tmp/my.conf')"