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

时间:2015-06-11 16:22:16

标签: ansible

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

grep -Fxq "127.0.0.1" /tmp/my.conf

8 个答案:

答案 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代替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]

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

答案 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
  • 如果文件包含" 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"和#34;你好,我喜欢ansible"最后。
  • 如果文件内容不包含" hello",则不会修改该文件。

答案 5 :(得分:1)

用户robo的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

答案 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过滤器配合使用,则可以使用此机制从匹配的行中获取特定值