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
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
.
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)
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).
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
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é.