2013-10-15 9 views
31

私は/etc/foo.txtに単純なファイルがあります。ファイルには、次のものが含まれています。私は上記の行のコメントを解除するには、次のansible脚本タスク持っ可能なラインファイルの複製行

#bar 

:私は最初ansible-脚本を実行すると

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

を、行はコメント解除し、/ etcます/

:私は再びansible-脚本を実行する場合、私は、次の取得、しかし

bar 

:foo.txtのは、今、以下が含まれています

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を追加する必要があります。

find 
if found 
    replace line found 
else 
    add line 

へ:つまり

find 
if found 
    replace line found 

が、これは操作の冪等を行い

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

これはからlineinfileの動作を変更します。

+5

これは最高の答えです。 –

関連する問題