Ansible — проверить, существует ли строка в файле

Я очень новичок в Ansible

Можно ли проверить, существует ли строка в файле с помощью Ansible.

Я хочу проверить, есть ли у пользователя доступ к серверу. это можно сделать на сервере с помощью cat /etc/passwd | grep username

но я хочу, чтобы Ansible останавливался, если пользователя нет.

Я пытался использовать lineinfile, но не могу заставить его вернуться.

код

 - name: find
   lineinfile: dest=/etc/passwd
               regexp=[user]
               state=present
               line="user"

Приведенный выше код добавляет пользователя в файл, если его там нет. Все, что я хочу сделать, это проверить. Я не хочу каким-либо образом изменять файл, возможно ли это

Спасибо.


person Frostie_the_snowman    schedule 19.07.2016    source источник
comment
Возможный дубликат Только проверьте, присутствует ли строка в файле (доступный)   -  person activatedgeek    schedule 19.07.2016


Ответы (4)


Я бы, вероятно, зарегистрировал и оценил переменную.

Для меня работает следующая простая книга:

- hosts: localhost
  tasks:

  - name: read the passwd file
    shell: cat /etc/passwd
    register: user_accts

  - name: a task that only happens if the user exists
    when: user_accts.stdout.find('hillsy') != -1
    debug: msg="user hillsy exists"
person hillsy    schedule 19.07.2016
comment
У Ansible возникла проблема с пользователем accts.stdout.find, это модуль или его следует запускать как оболочку? - person Frostie_the_snowman; 19.07.2016
comment
Это не совсем ни одна из этих вещей. Он проверяет содержимое переменной user_accts. См. документацию, которую я связал в ответе. На самом деле я не запускал код; Теперь я немного изменил свой ответ. Вышеупомянутое определенно работает для меня, хотя, очевидно, оно не делает ничего особенного, кроме вывода сообщения об успехе. - person hillsy; 19.07.2016

Это сложно. модуль lineinfile специально предназначен для изменения содержимого файла, но вы также можете использовать его для проверки правильности.

- name: find
  lineinfile: 
    dest: /etc/passwd
    line: "user"
  check_mode: yes
  register: presence
  failed_when: presence.changed

check_mode гарантирует, что он никогда не обновит файл. register сохраняет переменную, как указано. failed_when позволяет установить условие отказа, т. е. добавить пользователя, потому что он не был найден в файле.

Есть несколько итераций этого, которые вы можете использовать в зависимости от того, каким вы хотите видеть поведение. Документы lineinfile, относящиеся к state и regexp, должны позволить вам чтобы определить, является ли присутствие или отсутствие ошибкой и т. д., или вы можете выполнить not presence.changed и т. д.


person Jon Staples    schedule 27.09.2017
comment
Именно то, что я искал. - person Samuel Isola; 26.01.2018
comment
Мне нравится ответ, спасибо. Не совсем то, что я искал, но лучше. Я подумываю попросить вариант, в котором для обратных ссылок можно установить значение «да», и если строка не найдена (с указанным регулярным выражением), все равно добавьте текст. В этот раз не кажется. Я понимаю, через пример, который они приводят в документе для lineinfile, вариант использования для обратных ссылок и отсутствие добавления строки, если ее там нет. Но мне не нужно было бы регистрировать переменную, запускать два отдельных действия, чтобы убедиться, что строка непротиворечива, и убедиться, что файл находится в том состоянии, в котором я хочу, чтобы он был. Интересно, аппетит или недостатки. - person Gregg; 03.12.2019
comment
При установке state: absent и использовании regexp в приведенном выше коде вы получаете свойство found в зарегистрированном результате, показывающее, как часто ваше регулярное выражение было найдено. Свойство changed может сбивать с толку, так как оно верно и тогда, когда строка должна быть добавлена. - person skipperTux; 25.07.2020
comment
Был очень рад, когда нашел этот! Но у меня есть предложение по его продлению. Причина, по которой расширение «failed_when: присутствие.изменено» с помощью «или определение присутствия.исключение» может привести к обнаружению дополнительных ошибок. Одним из примеров является то, что файл не был изменен, потому что права доступа к файлу для тестируемого пользователя не были предоставлены. - person j0j0j0; 25.07.2020

Если вы хотите потерпеть неудачу, если нет пользователя:

tasks:
  - shell: grep username /etc/passwd
    changed_when: false

По умолчанию модуль shell завершится ошибкой, если код выхода команды отличен от нуля.
Таким образом, он выдаст вам ok, если имя пользователя есть, и выдаст ошибку в противном случае.
Я использую changed_when: false, чтобы предотвратить состояние changed при поиске.

person Konstantin Suvorov    schedule 19.07.2016
comment
Это тоже работает, но убивает остальные задачи, спасибо - person Frostie_the_snowman; 19.07.2016
comment
Вероятно, вы хотите ignore_errors: yes согласно docs.ansible.com/ansible/ . - person Xiong Chiamiov; 19.07.2016
comment
Исходный вопрос гласит но я хочу, чтобы Ansible останавливался, если пользователя нет — мой ответ делает именно это: выполнение останавливается, если пользователя нет. - person Konstantin Suvorov; 19.07.2016
comment
Что я имел в виду под своим вопросом, но я хочу, чтобы Ansible останавливался, если пользователя нет, так это то, что я хотел, чтобы задача останавливалась, а не плейбук. после прохождения ignore_errors: yes вы отвечаете также отлично. - person Frostie_the_snowman; 20.07.2016
comment
@Frostie_the_snowman рад, что мой ответ помог, но тогда я, честно говоря, не понимаю вашей задачи. Как правило, писать плейбуки с ignore_errors: yes — плохая идея. Если вам нужно условно выполнить некоторые другие задачи, основанные на факте существования пользователя, вы должны зарегистрировать переменную, как предлагает другой ответ. - person Konstantin Suvorov; 20.07.2016

Я использую следующий подход, используя только grep -q и зарегистрированную переменную.

Плюс в том, что это просто, недостаток в том, что у вас есть FAILED строка в вашем выводе. YMMV.

- name: Check whether foobar is defined in /bar/baz
  command:
    cmd: 'grep -q foobar /bar/baz'
  register: foobar_in_barbaz
  changed_when: false
  ignore_errors: true


- when: not foobar_in_barbaz.failed
  name: Do something when foobar is in /bar/baz
    ....


- when: foobar_in_barbaz.failed
  pause:
    seconds: 1
    content: |
      You do not seem to have a foobar line in /bar/baz
      If you add it, then magic stuff will happen!
person vjt    schedule 16.05.2020