The only way that I find to respect regex line break \n is concatenating everything in one line with double quote.
---
- name: Custom prompt output
lineinfile:
path: ~/.zshrc
line: "\n# Custom Prompt\nlocal user=\"%{$fg[yellow]%}%n%{$fg[white]%}#%{$fg[green]%}%m%{$reset_color%}\"\nPROMPT=\"${user} ${PROMPT}\""
state: present
The result is correctly as I expected, but is so ugly. Have a way to better this?
An option would be to use blockinfile
- name: Custom prompt output
blockinfile:
path: ~/.zshrc
create: yes
block: |
# Custom Prompt
local user="%{$fg[yellow]%}%n%{$fg[white]%}#%{$fg[green]%}%m%{$reset_color%}"
PROMPT="${user} ${PROMPT}"
Related
I am trying to write a playbook to add log forwarder lines to syslog.conf on AIX.
The tasks looks like this:
- set_fact:
log_servers:
- "auth.info\t#10.10.10.100"
- "*.info\t#log.example.com"
- lineinfile:
path: /etc/syslog.conf
regexp: '^{{item}}'
line: '{{item}}'
loop: "{{log_servers}}"
The first line is inserted with no issues, but I get a Python exception when the second line is encountered because of the leading asterisk.
An asterisk can be anywhere else in the line, but not at the start of the line. And escaping with a backslash (\*.info\t#log.example.com) causes a JSON parsing error, and a double backslash (\\*.info\t#log.example.com) just inserts a backslash at the front of the line.
Any advice on how to get around this?
Your issue is coming from the fact that you are trying to use the same string for a regex (where you need to escape the star) and for the line to add (where you don't need to escape the star).
There is a way to resolve this, though, it is to use the builtin regex_escape filter.
And so, your two task should become:
- set_fact:
log_servers:
- "auth.info\t#10.10.10.100"
- "*.info\t#log.example.com"
- lineinfile:
path: /etc/syslog.conf
regexp: '^{{ item | regex_escape() }}'
line: '{{ item }}'
loop: "{{ log_servers }}"
I want to remove only 'fsck.mode=auto' from the following line using ansible.
foo bar foo.bar=hold fsck.mode=auto foo foo bar foo
The hosts, root user and other privileges are set up else where in the project.
I prefer to use lineinfile if possible over replace. I don't want to delete the whole line but rather only remove whats in the regexp with ''.
- name: remove fsck
lineinfile:
dest: /etc/grub2.cfg
regexp: 'fsck.mode=auto'
line: ''
- name: Replacing the square brackets and single quotes on new VM IP address in hosts
hosts: 127.0.0.1
connection: local
become: true
tasks:
- name: Replacing the brackets from the end of the new ip with whitespace
replace:
path: /etc/ansible/hosts
regexp: \'\]
replace: ''
The above works for me to replace "']" with ''
edit: Just noticed you don't want to use 'replace' my bad. I believe you can use 'state=present' to replace using lineinfile
https://docs.ansible.com/ansible/2.4/lineinfile_module.html Take note of the 'backrefs' option
I think you are interested in backrefs. The code below does what you need. You can also play with white spaces if you want
- name: Change match only
lineinfile:
path: /whatever/file.txt
regexp: '^(. *)fsck.mode=auto (. *)$'
line: '\1\2'
backrefs: yes
Without those spaces between . and * (formatting piece of s>>t)
I want to add a few lines in a file as follows
*.file_size=100
*.db_size=1234
So, I just want the same format of the content added into one file along with that special characters through the ansible
You can use the blockinfile ansible module, below is an example for same,
- name: insert/update "Match User" configuration block in /etc/ssh/sshd_config
blockinfile:
path: /root/a.log
block: "*.file_size=100 *.db_size=1234"
marker: ""
You can also refer to the documentation here.
You can use | to do the job. | will add \n at the end of each line. No double quotes are needed here.
- name: insert something
lineinfile:
path: /home/aFile
line: |
*.file_size=100
*.db_size=1234
I'm new to Ansible and trying to modify a line in /etc/default/grub to enable auditing.
I need to add audit=1 within the quotes somewhere on a line that looks like:
GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap biosdevname=0 net.ifnames=0 rhgb quiet net.ifnames=0"
So far I've managed to delete the line and am only left with
net.ifnames=0, audit=1
when I use something like
lineinfile:
state: present
dest: /etc/default/grub
backrefs: yes
regexp: "net.ifnames=0"
line: "\1 audit=1"
Can this be done?
You may try this:
- lineinfile:
state: present
dest: /etc/default/grub
backrefs: yes
regexp: '^(GRUB_CMDLINE_LINUX=(?!.* audit)\"[^\"]+)(\".*)'
line: '\1 audit=1\2'
This will add audit=1 (with a leading space) just before closing double quote. It will not match without double quotes.
And it tries to be idempotent: doesn't match lines that already have audit (with a leading space) after GRUB_CMDLINE_LINUX=.
I'd recommend to use sites like regex101 to test your regular expressions first (there's also a substitution mode there).
When you're satisfied with the result, proceed with the Ansible task.
I wanted to make sure the parameter is also set to the correct value, so I used this replace invocation:
replace:
path: /etc/default/grub
regexp: '^(GRUB_CMDLINE_LINUX=(?:(?![" ]{{ option | regex_escape }}=).)*"?)\s*(?:{{ option | regex_escape }}=\S+\s*)?(.*")$'
replace: '\1 {{ option }}={{ value }}\2'
vars:
option: audit
value: 1
This works if the option wasn't present previously, if it was but had the wrong option (only changes the value then) and if the whole string was empty (but adds a space before the option then). Also, it uses regex_escape to correctly work with option names that contain dots and the likes, and you only have to specify them once.
When I use lineinfile in ansible it is not writing ', " characters
lineinfile: 'dest=/home/xyz state=present line="CACHES="default""'
it is giving CACHES=default
but the desired output is CACHES="default"
How to achieve this?
it appears you can escape the quotes:
- lineinfile: dest=/tmp/xyz state=present line="CACHES=\"default\""
That gives this output:
$ cat /tmp/xyz
CACHES="default"
You don't need to escape single quotes that are inside double quotes:
- lineinfile: dest=/tmp/xyz state=present line="CACHES=\"default\" foo='x'"
cat /tmp/xyz
CACHES="default" foo='x'
source: YAML specification, stackoverflow answer
Ansible 1.9.2 contains a bug (https://github.com/ansible/ansible/issues/10864), which fails to insert escaped double quotes at the beginning or end of the line.
E.g., the following
- name: /home/core/linetest
lineinfile: dest="/home/core/linetest" line="\"ma\"ok\"in\""
will result in missing first and last double-quotes (even though you escaped it).
#/home/core/linetest
ma"ok"in
To compensate for this bug, you could add a PREFIX to the starting and ending double quotes, and subsequently removing it.
- name: PREFIX first and last escaped double quotes with 'KUCF'
lineinfile: dest="/home/core/linetest" line="KUCF\"main\"KUCF"
- name: remove 'KUCF' PREFIX
replace: dest="/home/core/linetest" regexp="KUCF" replace=""
which should give you
#/home/core/linetest
"main"
Make sure that your chosen PREFIX will never be used in the context of the destination file. In general, the longer and more random the PREFIX, the less likely it will clash with existing content in your destination file.
Alternatively, you could upgrade your Ansible to the latest branch.
If the content to be substituted is in a variable higher up in the playbook, it seems that you need to escape the escape characters instead of the quotes, something like this
---
- hosts: tomcat
vars:
classpath: "CLASSPATH=\\\"$CATALINA_HOME/bin/foo.jar\\\""
tasks:
- lineinfile: dest="/tomcat/bin/setenv.sh" line="{{ classpath }}" state=present
ends up with a line like this in the resulting file
CLASSPATH="$CATALINA_HOME/bin/foo.jar"
Just a follow up to this, above examples did not work for me when trying to create a batch file on a windows box using win_lineinfile. The file was being created, the line was being inserted, but the quotes and backslashes were formatted terribly. This was with ansible 2.4. What I finally ended up doing per a co workers suggestion was some inline jinja templating;
- name: insert our batch file contents
win_copy:
dest: C:\QAAutomation\files\posauto.bat
force: yes
content: |
{% raw %}"C:\Program Files (x86)\NUnit 2.6.3\bin\nunit-console.exe" "C:\QAAutomation\files\1POS Automation\Application Files\Bin\Automation.dll" > "c:\QAAutomation\results\nunit-console-output.txt" {% endraw %}