Seulement vérifier si une ligne présente dans un fichier (ansible)

Dans ansible, je dois vérifier si une ligne particulière est présente dans un fichier ou non. Fondamentalement, j'ai besoin de convertir la commande suivante en une tâche ansible. Mon but est de vérifier seulement.

grep -Fxq "127.0.0.1" /tmp/my.conf
30
demandé sur mCeviker 2015-06-11 19:22:16

5 réponses

- 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

Mise à jour 2017-08-28: les anciennes versions Ansible doivent utiliser always_run: yes au lieu de check_mode: no.

31
répondu Antonis Christofides 2017-11-28 09:34:10

Utilisez check_mode, register et failed_when en concert. Cela échoue la tâche si le module lineinfile apporte des modifications au fichier en cours de vérification. Check_mode assure que rien ne changera même si cela le ferait autrement.

- name: "Ensure /tmp/my.conf contains '127.0.0.1'"
  lineinfile:
    path: /tmp/my.conf
    line: "127.0.0.1"
    state: present
  check_mode: yes
  register: contents_would_have
  failed_when: (contents_would_have | changed) or (contents_would_have | failed)
20
répondu LHSnow 2017-08-23 14:56:06

Avec la solution acceptée, même si vous ignorez les erreurs, vous obtiendrez toujours une sortie d'erreur rouge laide sur la première tâche s'il n'y a pas de correspondance:

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

Si vous voulez moins de commentaires, vous pouvez utiliser awk au lieu de grep. awk ne retournera pas une erreur sur un non-match, ce qui signifie que la première tâche de vérification ci-dessous ne fera pas d'erreur indépendamment d'une correspondance ou d'un non-match:

- 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")

Notez que ma deuxième tâche utilise le filtre de correspondance car awk renvoie la chaîne correspondante si elle trouve un correspondre.

L'alternative ci-dessus produira la sortie suivante, que la tâche de vérification ait ou non une correspondance:

TASK: [Check whether /tmp/my.conf contains "127.0.0.1"] ***********************
ok: [localhost]

IMHO c'est une meilleure approche car vous n'ignorerez pas d'autres erreurs dans votre première tâche (par exemple si le fichier spécifié n'existait pas).

13
répondu mixja 2015-09-27 04:58:48

Utilisez la commande Ansible lineinfile, mais cette commande mettra à jour le fichier avec la ligne si elle n'existe pas.

- lineinfile: dest=/tmp/my.conf line='127.0.0.1' state=present
4
répondu VSK 2015-06-11 16:38:45

Une autre façon est d'utiliser le "remplacer le module "puis" lineinfile module".

L'algo est fermé à celui utilisé lorsque vous voulez changer les valeurs de deux variables.

  • tout d'abord, utilisez "remplacer le module" pour détecter si la ligne que vous recherchez est ici et la changer avec quelque chose d'autre. (Comme la même ligne + quelque chose à la fin).
  • Alors, si "remplacer" est vrai, Cela signifie que votre ligne est ici, puis remplacez la nouvelle ligne avec une particularité, avec la nouvelle ligne semblant.
  • sinon la ligne que vous recherchez n'est pas ici.

Exemple:

# 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
  • Si le fichier contient "bonjour", il deviendra "bonjour à vous", puis "bonjour, j'adore ansible" à la fin.
  • Si le contenu du fichier ne contient pas "hello", le fichier n'est pas modifié.

Avec la même idée, vous pouvez faire quelque chose si lineSearched est ici:

# 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
  • Si le fichier contient "bonjour", la ligne contient toujours "bonjour" et "bonsoir, j'adore ansible" à la fin.
  • Si le contenu du fichier ne contient pas "hello", le fichier n'est pas modifié.
3
répondu Je.Go 2016-11-30 15:16:00