Ansible:如果不存在则插入行
Ansible: Insert line if not exists
我正在尝试使用 ansible 在 属性 文件中插入一行。
我想添加一些 属性 如果它不存在,但如果 属性 已经存在于文件中则不替换它。
我添加到我的 ansible 角色
- name: add couchbase host to properties
lineinfile: dest=/database.properties regexp="^couchbase.host" line="couchbase.host=127.0.0.1"
但是如果 属性 值已经存在于文件中,它会将 属性 值替换回 127.0.0.1。
我做错了什么?
lineinfile
模块确保文件中存在 line
中定义的行,并且该行由您的 regexp
标识。因此,无论您的设置已经具有什么值,它都将被您的新 line
.
覆盖
如果您不想覆盖该行,您首先需要测试内容,然后将该条件应用于 lineinfile
模块。没有用于测试文件内容的模块,因此您可能需要使用 shell
命令 运行 grep
并检查 .stdout
的内容。像这样(未经测试):
- name: Test for line
shell: grep -c "^couchbase.host" /database.properties || true
register: test_grep
然后将条件应用于您的 lineinfile
任务:
- name: add couchbase host to properties
lineinfile:
dest: /database.properties
line: couchbase.host=127.0.0.1
when: test_grep.stdout == "0"
然后可以删除 regexp
,因为您已经确定该行不存在,所以它永远不会匹配。
但也许您正在做一些事情。文件中的那一行是从哪里来的?当您使用 Ansible 管理您的系统时,不应该有其他机制干扰相同的配置文件。也许您可以通过为您的角色添加 default
值来解决这个问题?
千里迢迢 "Trials and errors" 我来到这里:
- name: check existence of line in the target file
command: grep -Fxq "ip addr add {{ item }}/32 dev lo label lo:{{ app | default('app') }}" /etc/rc.local
changed_when: false
failed_when: false
register: ip_test
with_items:
- "{{ list_of_ips }}"
- name: add autostart command
lineinfile: dest=/etc/rc.local
line="ip addr add {{ item.item }}/32 dev lo label lo:{{ app | default('app') }}"
insertbefore="exit 0"
state=present
when: item.rc == 1
with_items:
- "{{ ip_test.results }}"
这是我能够让它工作的唯一方法。
- name: checking for host
shell: cat /database.properties | grep couchbase.host | wc -l
register: test_grep
- debug: msg="{{test_grep.stdout}}"
- name: adding license server
lineinfile: dest=/database.properties line="couchbase.host=127.0.0.1"
when: test_grep.stdout == "0"
与此处介绍的想法相同:
步骤是:
- 尝试更换线路。
- 如果替换mod改一下,恢复
- 如果替换 mod 没有改变,添加行
示例
# Vars
- name: Set parameters
set_fact:
ipAddress : "127.0.0.1"
lineSearched : "couchbase.host={{ ipAddress }}"
lineModified : "couchbase.host={{ ipAddress }} hello"
# Tasks
- name: Try to replace the line
replace:
dest : /dir/file
replace : '{{ lineModified }} '
regexp : '{{ lineSearched }}$'
backup : yes
register : checkIfLineIsHere
# If the line not is here, I add it
- name: Add line
lineinfile:
state : present
dest : /dir/file
line : '{{ lineSearched }}'
regexp : ''
insertafter: EOF
when: checkIfLineIsHere.changed == false
# If the line is here, 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
好的,这是我天真的解决方案...可能不是跨平台的原生 Ansible(我刚开始使用这个工具并且还在学习它),但绝对更短:
- name: Update /path/to/some/file
shell: grep -q 'regex' /path/to/some/file && echo exists || echo 'text-to-append' >> /path/to/some/file
register: result
changed_when: result.stdout.find('exists') == -1
- name: add couchbase.host to properties, works like add or replace
lineinfile:
state: present
dest: /database.properties
regexp: '^couchbase.host'
line: 'couchbase.host=127.0.0.1'
我们已经尝试了以下方法并且效果很好。如果系统日志文件不存在,我们的场景需要在系统日志文件中输入 "compress"。
- name: Checking compress entry present if not add entry
lineinfile:
path: /etc/logrotate.d/syslog
regexp: " compress"
state: present
insertafter: " missingok"
line: " compress"
如果您使用 backrefs.
,它似乎不起作用
以下示例不添加一行
- name: add hosts file entry
lineinfile:
path: "/etc/hosts"
regexp: "foohost"
line: "10.10.10.10 foohost"
state: present
backrefs: yes
删除反向引用后,我将我的行添加到文件中
- name: add hosts file entry
lineinfile:
path: "/etc/hosts"
regexp: "foohost"
line: "10.10.10.10 foohost"
state: present
这可以通过简单地使用 lineinfile
和 check_mode
:
- name: Check if couchbase.host is already defined
lineinfile:
state: absent
path: "/database.properties"
regexp: "^couchbase.host="
check_mode: true
changed_when: false # This just makes things look prettier in the logs
register: check
- name: Define couchbase.host if undefined
lineinfile:
state: present
path: "/database.properties"
line: "couchbase.host=127.0.0.1"
when: check.found == 0
- name: add couchbase.host to properties, works like add or replace
lineinfile:
path: /database.properties
regexp: '^couchbase.host=(?!(127.0.0.1))\b'
line: 'couchbase.host=127.0.0.1'
此代码将替换除 couchbase.host=127.0.0.1
之外的任何行 ^couchbase.host=*
或将添加新行(如果不存在)
我正在尝试使用 ansible 在 属性 文件中插入一行。 我想添加一些 属性 如果它不存在,但如果 属性 已经存在于文件中则不替换它。
我添加到我的 ansible 角色
- name: add couchbase host to properties
lineinfile: dest=/database.properties regexp="^couchbase.host" line="couchbase.host=127.0.0.1"
但是如果 属性 值已经存在于文件中,它会将 属性 值替换回 127.0.0.1。
我做错了什么?
lineinfile
模块确保文件中存在 line
中定义的行,并且该行由您的 regexp
标识。因此,无论您的设置已经具有什么值,它都将被您的新 line
.
如果您不想覆盖该行,您首先需要测试内容,然后将该条件应用于 lineinfile
模块。没有用于测试文件内容的模块,因此您可能需要使用 shell
命令 运行 grep
并检查 .stdout
的内容。像这样(未经测试):
- name: Test for line
shell: grep -c "^couchbase.host" /database.properties || true
register: test_grep
然后将条件应用于您的 lineinfile
任务:
- name: add couchbase host to properties
lineinfile:
dest: /database.properties
line: couchbase.host=127.0.0.1
when: test_grep.stdout == "0"
然后可以删除 regexp
,因为您已经确定该行不存在,所以它永远不会匹配。
但也许您正在做一些事情。文件中的那一行是从哪里来的?当您使用 Ansible 管理您的系统时,不应该有其他机制干扰相同的配置文件。也许您可以通过为您的角色添加 default
值来解决这个问题?
千里迢迢 "Trials and errors" 我来到这里:
- name: check existence of line in the target file
command: grep -Fxq "ip addr add {{ item }}/32 dev lo label lo:{{ app | default('app') }}" /etc/rc.local
changed_when: false
failed_when: false
register: ip_test
with_items:
- "{{ list_of_ips }}"
- name: add autostart command
lineinfile: dest=/etc/rc.local
line="ip addr add {{ item.item }}/32 dev lo label lo:{{ app | default('app') }}"
insertbefore="exit 0"
state=present
when: item.rc == 1
with_items:
- "{{ ip_test.results }}"
这是我能够让它工作的唯一方法。
- name: checking for host
shell: cat /database.properties | grep couchbase.host | wc -l
register: test_grep
- debug: msg="{{test_grep.stdout}}"
- name: adding license server
lineinfile: dest=/database.properties line="couchbase.host=127.0.0.1"
when: test_grep.stdout == "0"
与此处介绍的想法相同:
步骤是:
- 尝试更换线路。
- 如果替换mod改一下,恢复
- 如果替换 mod 没有改变,添加行
示例
# Vars
- name: Set parameters
set_fact:
ipAddress : "127.0.0.1"
lineSearched : "couchbase.host={{ ipAddress }}"
lineModified : "couchbase.host={{ ipAddress }} hello"
# Tasks
- name: Try to replace the line
replace:
dest : /dir/file
replace : '{{ lineModified }} '
regexp : '{{ lineSearched }}$'
backup : yes
register : checkIfLineIsHere
# If the line not is here, I add it
- name: Add line
lineinfile:
state : present
dest : /dir/file
line : '{{ lineSearched }}'
regexp : ''
insertafter: EOF
when: checkIfLineIsHere.changed == false
# If the line is here, 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
好的,这是我天真的解决方案...可能不是跨平台的原生 Ansible(我刚开始使用这个工具并且还在学习它),但绝对更短:
- name: Update /path/to/some/file
shell: grep -q 'regex' /path/to/some/file && echo exists || echo 'text-to-append' >> /path/to/some/file
register: result
changed_when: result.stdout.find('exists') == -1
- name: add couchbase.host to properties, works like add or replace
lineinfile:
state: present
dest: /database.properties
regexp: '^couchbase.host'
line: 'couchbase.host=127.0.0.1'
我们已经尝试了以下方法并且效果很好。如果系统日志文件不存在,我们的场景需要在系统日志文件中输入 "compress"。
- name: Checking compress entry present if not add entry
lineinfile:
path: /etc/logrotate.d/syslog
regexp: " compress"
state: present
insertafter: " missingok"
line: " compress"
如果您使用 backrefs.
,它似乎不起作用以下示例不添加一行
- name: add hosts file entry
lineinfile:
path: "/etc/hosts"
regexp: "foohost"
line: "10.10.10.10 foohost"
state: present
backrefs: yes
删除反向引用后,我将我的行添加到文件中
- name: add hosts file entry
lineinfile:
path: "/etc/hosts"
regexp: "foohost"
line: "10.10.10.10 foohost"
state: present
这可以通过简单地使用 lineinfile
和 check_mode
:
- name: Check if couchbase.host is already defined
lineinfile:
state: absent
path: "/database.properties"
regexp: "^couchbase.host="
check_mode: true
changed_when: false # This just makes things look prettier in the logs
register: check
- name: Define couchbase.host if undefined
lineinfile:
state: present
path: "/database.properties"
line: "couchbase.host=127.0.0.1"
when: check.found == 0
- name: add couchbase.host to properties, works like add or replace
lineinfile:
path: /database.properties
regexp: '^couchbase.host=(?!(127.0.0.1))\b'
line: 'couchbase.host=127.0.0.1'
此代码将替换除 couchbase.host=127.0.0.1
之外的任何行 ^couchbase.host=*
或将添加新行(如果不存在)