在ansible中,我需要检查文件中是否存在特定行。基本上,我需要将以下命令转换为ansible任务。我的目标是只检查。
grep -Fxq "127.0.0.1" /tmp/my.conf
答案 0 :(得分:38)
一致使用check_mode,register和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)
答案 1 :(得分:37)
- 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 :(得分:14)
使用已接受的解决方案,即使您忽略错误,如果没有匹配,您仍会在第一个任务上获得丑陋的红色错误输出:
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]
恕我直言,这是一种更好的方法,因为您不会忽略第一项任务中的其他错误(例如,如果指定的文件不存在)。
答案 3 :(得分:5)
使用ansible lineinfile命令,但如果该行不存在,此命令将使用该行更新该文件。
- lineinfile: dest=/tmp/my.conf line='127.0.0.1' state=present
答案 4 :(得分:3)
另一种方法是使用"替换模块"那么" lineinfile module"。
当您想要更改两个变量的值时,算法将关闭。
示例:
# 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
有了同样的想法,如果lineSearched在这里,你可以做点什么:
# 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
答案 5 :(得分:1)
用户robo的regexp
和absent
方法非常干净,因此我将其充实以方便使用:
- 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
register: out
- debug:
msg: "Yes, line exists."
when: out.changed
- debug:
msg: "Line does NOT exist."
when: not out.changed
答案 6 :(得分:0)
您可以在这种情况下使用文件插件。
- 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')"
答案 7 :(得分:0)
另一种对其他用途也有用的解决方案是逐行遍历文件的内容
go mod graph | grep github.com/Shopify/sarama
例如,如果您将其与jinja regex_replace过滤器配合使用,则可以使用此机制从匹配的行中获取特定值