Understanding lineinfile

Hi.

I want to use lineinfile module to change my host table like this :

127.0.0.1 localhost

to

127.0.0.1 localhost project1 project2 newproject

so I was thinking to do something like :

action: lineinfile name=/etc/hosts regexp=^127.0.0.1 … backup=yes

But base on the examples I don’t know if there is a way to add at the end of the line (not the file) or not ?

Thanks.

lineinfile cannot edit lines that already exist, though I would love
to see a pull request to teach it this ability. (Perhaps a
'edit=yes|no' ?)

Workaround for now is to template out the file entirely.

Thanks, I will live to see that too.

This seems to work?

action: lineinfile name=/tmp/hosts regexp=“^127.0.0.1.*localhost” line=“127.0.0.1\tlocalhost project1 project2 newproject”

on a side note, is it possible to implement printf function to be able to format output with f. ex. %-10s?

> This seems to work?
>
> action: lineinfile name=/tmp/hosts regexp="^127\.0\.0\.1.*localhost"
> line="127.0.0.1\tlocalhost project1 project2 newproject"

Well, does it, or doesn't it work?

AFAIK it shouldn't -- you'll end up with two entries for the loopback
address.

on a side note, is it possible to implement printf function to be able to
format output with f. ex. %-10s?

Look at templates with which you can do that kind of stuff with Jinja2.
Those are probably also find for generating your /etc/hosts file.

        -JP

It works based on that it replaces the match with the content of line=, so not truly an edit/add end of match.

If you get duplicate lines, it is because the regexp doesn’t match any lines. To allow it to be more flexible, use wildcards… yet not too much that it finds multiple entries (as always with regex).

it doesn’t work.

if you have for example :

127.0.0.1 localhost project1

and you want to add “newproject” it basically replace the line with :

127.0.0.1 localhost newproject

so it doesn’t add to the end of the line.

Please note 0.8 regexes don't require to start with "^" and "$" anymore.

Used the module quite recently for configuring ansible commander and
it works fine for what it says it does.

We didn't say it edits lines and go back and read what JP Mens said
about templates.

I understand, I just tested to see if PJ was right or not.

It should be noted that I tested with 0.7. However, I can’t see any difference in the code between current devel and 0.7 that would suggest that things have changed.

if you have for example :
127.0.0.1 localhost project1
and you want to add “newproject” it basically replace the line with :
127.0.0.1 localhost newproject
so it doesn’t add to the end of the line.

It sounds like you missed project1 in your line=. For above try:
regexp=“127.0.0.1.*” line=“127.0.0.1\tlocalhost\tproject1\tnewproject”

Michael:

In regards to templates, I think it depends a bit on how you decide to handle system files and who the audience is:

a) by having a central, version controlled repository of the actual files and copy them out.
b) assembling fragments of files to build them up.
c) using regex to find/add/modify entries in the file.

Both (a) and (b) would require you to verify each file every time you apply patches to the system that affects the specific file, while (c) would work regardless of changes in the files, but makes it more complicated to handle/update for people who aren’t familiar with ansible.

Because of the latter and because it’s easier to see who changed what in an easier way, we’re leaning towards going with option (a).

May be it would be more manageable to have separate lines?
127.0.0.1 localhost
127.0.0.1 project1
127.0.0.1 project2
127.0.0.1 newproject

Absolutely. This is why I resisted including lineinfile in the first
place. While it has uses, it should be a last resort, and only when
you need to have the user be able to edit the file and also centrally
manage it. This is ALWAYS going to be dangerous (not just in
Ansible, in any tool) as the user can break the file and you won't be
able to fix it because you aren't representing the entire
state of the file.