web-dev-qa-db-fra.com

Vérifier seulement si une ligne est 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, je dois convertir la commande suivante en une tâche ansible. Mon but est seulement de vérifier.

grep -Fxq "127.0.0.1" /tmp/my.conf
37
Ansuman Bebarta
- 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

Update 2017-08-28: Les anciennes versions de Ansible doivent utiliser always_run: yes au lieu de check_mode: no.

34

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

- 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)
36
LHSnow

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 souhaitez une sortie moins détaillée, vous pouvez utiliser awk au lieu de grep. awk ne renverra pas d'erreur sur une non-correspondance, ce qui signifie que la première tâche de vérification ci-dessous ne provoquera pas d'erreur, qu'il y ait correspondance ou non-correspondance:

- 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 une correspondance.

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

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

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

14
mixja

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
5
VSK

Une autre méthode consiste à utiliser le "module de remplacement", puis le "module lineinfile".

L'algo est proche de 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 présente et changez-la avec quelque chose d'autre. (Même ligne + quelque chose à la fin).
  • Ensuite, si "replace" est vrai, cela signifie que votre ligne est ici, puis remplacez la nouvelle ligne par une particularité, avec la nouvelle ligne à la recherche.
  • 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'aime 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 la ligne recherchée 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 contiendra toujours "bonjour" et "bonjour, j'aime ansible" à la fin.
  • Si le contenu du fichier ne contient pas "hello", le fichier n'est pas modifié.
3
Je.Go

La méthode regexp & absent de robo est assez propre, je l'ai donc développée ici pour une utilisation facile:

- 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
Donn Lee