only_if file does not contain a certain line

Not sure If I am doing this the proper way but I want to check a file for a certain line and only execute a command if the file does not contain this line. I see there is a lineinfile command but that seems to be for modifying files not really for saving into a register so I can run an only_if on it. Is there a way to achieve this?

Hi,

Not sure If I am doing this the proper way but I want to check a file for a certain line
and only execute a command if the file does not contain this line. I see there is a
lineinfile command but that seems to be for modifying files not really for saving
into a register so I can run an only_if on it. Is there a way to achieve this?

Here's a somewhat contrived example I used a while back when evaluating ansible for various ways of doing things. Just say I had the need to enable a service out of inetd on a debian system. Usually I'd use something like the following to enable it:

  tasks:
  - name: Daytime | enable inetd daytime
    action: command /usr/sbin/update-inetd --comment-chars "#" --enable daytime

The problem here is that it will run every single time I run the playbook and thus show me a "changed" state every time. It won't be doing bad things when it ran every time but I wanted to only see a "changed" entry when it actually had to make a change. So, I wanted to simplistically check /etc/inetd.conf for the service being already active.

The above became:

  tasks:
  - name: Daytime | check whether daytime is enabled
    # We can't use grep -c as this sets a return code of 1 when there
    # are no matching records
    # Instead we simply pass through to wc -l which gives the same
    # numeric result but with a successful execution in all cases.
    action: shell grep -E '^daytime' /etc/inetd.conf | wc -l
    register: has_inetd_daytime

  - name: Daytime | enable inetd daytime
    action: command /usr/sbin/update-inetd --comment-chars "#" --enable daytime
    only_if: "${has_inetd_daytime.stdout} == 0"

There are various approaches around tackling the no results and subsequent return code situation commented in the task above but I'm sure you get the general point (for example, see http://ansible.cc/docs/playbooks.html#tasks-list).

Cheers,

Andrew

Totally. Here's an example of making something vary based on an exit
code that I just simplified.

https://github.com/ansible/ansible/blob/devel/examples/playbooks/register_logic.yml

Why are you using shell instead of command in those examples? I saw that shell is used when you need to have redirection but in this example would command be a fine alternative? Just want to make sure I understand the full difference of the two.

Regards

I used shell because it didn't matter in this particular case. Using
command is generally a smart idea.

Yep, exactly!

The wc -l usage can allow you to omit the 'ignore_errors' part in my
example, though it's useful to do it the other way if you are running
some command
that only has access to exit codes.

Andrew (and list members), have you found a solution to your problem hereunder (getting the result of a grep command without your playbook showing a “changed” state every time)?

There was a previously suggestion to use a module for it, on the original thread. No need to start a new thread :slight_smile:

Ultimately though, running sed is going to be a bit unreliable as you won’t know what else is in the file, and you should template the file if you can.

There have been previous patch attempts to make a command return changed=False depending on the return code, though none quite got finished, unfortunately

I would accept something like:

shell … changed_rc=0,1,2 etc

There was a previously suggestion to use a module for it, on the original thread. No need to start a new thread :slight_smile:

I replied to this thread because Andrew’s message made me believe he has found a solution to the changed state “issue”. Sorry :slight_smile:

Ultimately though, running sed is going to be a bit unreliable as you won’t know what else is in the file, and you should template the file if you can.

You convinced me. For my use case (setting APT repositories in /etc/apt/sources.list), it’s better to just template the file.

There have been previous patch attempts to make a command return changed=False depending on the return code, though none quite got finished, unfortunately

I would accept something like:

shell … changed_rc=0,1,2 etc

Ok. If I come across a use case where a changed_rc option is really needed, I won’t hesitate to submit a patch :slight_smile:

Thank you for your help Michael!