2013-10-15 3 views
31

У меня есть простой файл в /etc/foo.txt. Файл содержит следующее:Ansible lineinfile дублирует строку

#bar 

У меня есть следующий анзибль PlayBook задача раскомментировать строку выше:

- name: test lineinfile 
    lineinfile: backup=yes state=present dest=/etc/foo.txt 
       regexp='^#bar' 
       line='bar' 

Когда я впервые запустить анзибль-пьесы, линия получает незакомментированную и/и т.д./foo.txt теперь содержит следующее:

bar 

Однако, если я снова запустить анзибль-пьес, я получаю следующее:

bar 
bar 

Если я запустить его еще раз, то файл /etc/foo.txt будет выглядеть следующим образом:

bar 
bar 
bar 

Как избежать этого дублирования строк? Я просто хочу раскомментировать «#bar» и покончить с этим.

ответ

50

Проблема в регулярном выражении задачи соответствует только прокомментированной строке, #bar. Чтобы быть идемпотентным, задача lineinfile должна соответствовать как прокомментированному состоянию , так и. Таким образом он расторгнет #bar, но пройдет bar без изменений.

Эта задача должна делать то, что вы хотите: «?»

- name: test lineinfile 
    lineinfile: 
    backup=yes 
    state=present 
    dest=/etc/foo.txt 
    regexp='^#?bar' 
    line='bar' 

Примечание единственное изменение было Добавление к регулярному выражению.

+0

Но это всегда изменяет файл. Мое понимание заключалось в том, что строка только вставлена ​​(изменена в файл), когда соответствие регулярного выражения. – jdevora

+0

До тех пор, пока файл выходит одинаково каждый раз, задача является идемпотентной. Это все, что имеет значение. – joemaller

+0

Я обнаружил, что, если вы используете 'insertafter' в сочетании с этим, вы снова получите повторяющиеся строки. 'insertafter' нарушает эту формулу. –

55

Вам необходимо добавить backrefs = yes, если вы не хотите менять свое регулярное выражение.

- name: test lineinfile 
    lineinfile: backup=yes state=present dest=/etc/foo.txt 
       regexp='^#bar' backrefs=yes 
       line='bar' 

Это изменяет поведение lineinfile от:

find 
if found 
    replace line found 
else 
    add line 

к:

find 
if found 
    replace line found 

Другими словами, это делает операцию идемпотент.

+5

Это лучший ответ. –

Смежные вопросы