LoginSignup
3
3

More than 5 years have passed since last update.

Ansibleのlineinfileモジュールでタブ文字("\t")を挿入する際

Last updated at Posted at 2014-10-12

lineinfileのクォート処理で、バグらしきものを見つけたので、メモ。
あとで GitHub に issue 登録しておこうかしら。 登録した(#174)。

2014/10/15追記
どうも " '...' " によるクォート処理は、他の箇所でも怪しい。
" '...' " で変な動作になったら、' "..." '(ダブル/シングルを逆にする)を試すと、うまく動くことがあるみたい。

環境

Ansible 1.7.2で発生。1.7.1 では発生しないようだ。

今回は、"pip install ansible"して、1.7.2 を使ったら発生。びっくりした。
"yum install ansible"で 1.7.1 に戻したら治まった。

OSはCentOS7。

問題

ある条件が揃うと、lineinfileの挿入行で "\t" を展開できない。

例えば、こんなテキストファイルがあったとして(インデントは"\t")

# a sample text

        Insert after this line: single-quoted-nomix '...'
        the next line

        Insert after this line: double-quoted-nomix "..."
        the next line

        Insert after this line: single-quoted-mix '"..."'
        the next line

        Insert after this line: double-quoted-mix "'...'"
        the next line

        Insert after this line: single-quoted-jinja2-mix '{{xx}} "..."'
        the next line

        Insert after this line: double-quoted-jinja2-mix "{{xx}} '...'"
        the next line

以下のAnsible playbookは期待通りに動作しない。ケース4がダメ。"\t"が効かない。

--- # file: lineinfile.yml

- hosts: all

  gather_facts: False

  vars:
    original_file: ./test.txt.org
    target_file: ./test.txt
    fresh_start: yes

  tasks:
    - name: copy the data file
      copy: src={{ original_file }} dest={{ target_file }}
        force={{ fresh_start }}

    - name: case1 insert the line '...'
      lineinfile: dest={{ target_file }} state=present
        insertafter='\t.*single-quoted-nomix'
        line='\ta line with tab 1'
        regexp='a line with tab 1'

    - name: case2 insert the line "..."
      lineinfile: dest={{ target_file }} state=present
        insertafter="\t.*double-quoted-nomix"
        line="\ta line with tab 2"
        regexp="a line with tab 2"

    - name: case3 insert the line with '"..."'
      lineinfile: dest={{ target_file }} state=present
        insertafter='\t.*single-quoted-mix'
        line='\ta line with "tab" 3'
        regexp='a line with "tab" 3'

    - name: case4 insert the line "'...'"
      lineinfile: dest={{ target_file }} state=present
        insertafter="\t.*double-quoted-mix"
        line="\ta line with 'tab' 4"
        regexp="a line with 'tab' 4"

    - name: case5 insert the line with '"..."' with jinja2
      lineinfile: dest={{ target_file }} state=present
        insertafter='\t.*single-quoted-jinja2-mix'
        line='{{ "\t" }}a line with "tab" 5'
        regexp='a line with "tab" 5'

    - name: case6 insert the line "'...'" with jinja2
      lineinfile: dest={{ target_file }} state=present
        insertafter="\t.*double-quoted-jinja2-mix"
        line="{{ '\t' }}a line with 'tab' 6"
        regexp="a line with 'tab' 6"

結果

case4だけ、"\t" が文字列として挿入されてしまった。

# a sample text

        Insert after this line: single-quoted-nomix '...'
        a line with tab 1
        the next line

        Insert after this line: double-quoted-nomix "..."
        a line with tab 2
        the next line

        Insert after this line: single-quoted-mix '"..."'
        a line with "tab" 3
        the next line

        Insert after this line: double-quoted-mix "'...'"
\ta line with 'tab' 4
        the next line

        Insert after this line: single-quoted-jinja2-mix '{{xx}} "..."'
        a line with "tab" 5
        the next line

        Insert after this line: double-quoted-jinja2-mix "{{xx}} '...'"
        a line with 'tab' 6
        the next line

回避方法

以下のようにすれば問題ない様子。

  1. Ansible 1.7.2は使わない
  2. クォートを混ぜない(解にならないかも)
  3. 外側のクォートをシングルクォートにして、そのなかで "\t" を使う
  4. Jinja2 を駆使する

こんなところで、なんでバグったんだろうな~。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3