仅检查文件中是否存在一行(ansible)

问题描述 投票:41回答:7

在ansible中,我需要检查文件中是否存在特定行。基本上,我需要将以下命令转换为ansible任务。我的目标是只检查。

grep -Fxq "127.0.0.1" /tmp/my.conf
ansible
7个回答
38
投票
- 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


39
投票

一致使用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)

13
投票

使用公认的解决方案,即使您忽略错误,如果没有匹配,您仍会在第一个任务上获得丑陋的红色错误输出:

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而不是grepawk不会在不匹配时返回错误,这意味着无论匹配或不匹配,下面的第一个检查任务都不会出错:

- 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]

恕我直言这是一个更好的方法,因为你不会忽略你的第一个任务中的其他错误(例如,如果指定的文件不存在)。


5
投票

使用ansible lineinfile命令,但是如果该行不存在,此命令将使用该行更新该文件。

- lineinfile: dest=/tmp/my.conf line='127.0.0.1' state=present

3
投票

另一种方法是使用“替换模块”然后使用“lineinfile模块”。

当您想要更改两个变量的值时,算法将关闭。

  • 首先,使用“替换模块”来检测您要查找的行是否在此处,并使用其他内容进行更改。 (就像同一行+最后的东西)。
  • 然后,如果“替换”为真,则表示您的行在此处,然后用新的行查找具有特殊性的新行。
  • 否则你要找的那条线不在这里。

例:

# 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
  • 如果文件中包含“hello”,那么它最终会成为“你好”,然后是“你好,我喜欢ansible”。
  • 如果文件内容不包含“hello”,则不修改该文件。

使用相同的想法,如果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
  • 如果文件包含“hello”,那么该行仍将包含“hello”和“hello,i love ansible”。
  • 如果文件内容不包含“hello”,则不修改该文件。

2
投票

用户机器人的regexpabsent方法非常干净,所以我在这里充实它以方便使用:

- 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

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')"
© www.soinside.com 2019 - 2024. All rights reserved.