How to use escape characters in Ansible shell/grep command - shell

I need to extract a hostname from a URL in a file on my remote host to then use that value in another task.
I have the following task in my playbook:
- name: Extract server name
shell: "grep ^serverURL=https:\/\/(.*)\/XMLRPC <filename>"
register: <variable>
But when I try and run it I get the following error (cut down to relevant bits):
Found unknown escape character. The offending line appears to be:
- name: Extract server name
shell: "grep ^serverURL=https:\/\/(.*)\/XMLRPC <filename>"
^ here
It seems there is a value started with a quote and the YAML parser is expecting to see the line ended with the same kind of quote.
Obviously it does start and finish with double quotes but the carat is at the escape character in my grep query, so it seems reasonable to think that this is the cause of the problem; if I remove the backslashes my grep query doesn't return anything.
How can I escape this correctly please?

Related

Ansible 2.9 - Escape a single "\" backslash being passed into win_command from variable

vars:
- windowsLogonAccount: NT AUTHORITY\SYSTEM
tasks:
- name: Install Agent via CMD
win_command: "config.cmd --windowsLogonAccount '{{ windowsLogonAccount }}'"
args:
chdir: "c:/agent"
I'm attempting to get just a single backslash to pass via Ansible to Windows. I've tried double backslashes "\\" and I've tried {{ var | safe }}, but without luck. I'm hoping somebody in the community can point me in the right direction. I can't believe it is as complicated as some of the other examples I've seen using replace and regex...
Everything I try I keep getting a double backslash:
2021-10-19T04:45:52.8643709Z TASK [Get Variable Output to Screen] *******************************************
2021-10-19T04:45:52.9042957Z "msg": "My Variable Test Area 'NT AUTHORITY\\SYSTEM'"
I came here having not the exact same problem, but a similar one (passing an escaped backslash (\\) to the command), and my solution might also help here. When inserting variables into the command for command or win_command, it is always good to pipe the variable to the quote filter to preserve the content of the variable as is. In your case:
win_command: "config.cmd --windowsLogonAccount {{ windowsLogonAccount | quote }}"
----Resolved----
So this is a unique thing with Ansible Outputs to Terminal. They write output in valid JSON and thus "auto" escape special characters like backslashes in the output. But the actual value passed during run-time does not contain both back slashes. I'm posting this in case any other Ansible noobs run into this surprise.
Example output to screen:
2021-10-19T04:46:11.6003956Z: [COMPUTERNAME]: CHANGED! => {"changed": true, "cmd": "config.cmd --unattended --windowsLogonAccount 'NT AUTHORITY\SYSTEM'
Actual output to host:
config.cmd --unattended --windowsLogonAccount 'NT AUTHORITY\SYSTEM'

What is the purpose of ">" in "shell: >" within an Ansible task?

What function does the ">" character serve, in a simple Ansible task that executes a shell command? For the life of me I can't find documentation or mention of this! Here is the template for the task:
- name: <task_name>
shell: >
<command>
Thank you.
The > is a mark for yaml. It means that the following lines will be compressed into a single string with leading indentation compressed to a single space. There are some technical details regarding leading indentation that will modify how the final string is generated, but to the yaml parser the following are equivalent:
- name: task_name
shell: >
this is some
arbitrary string which may
be a shell command
- name: task2_name
shell: this is some arbitrary string which may be a shell command

lineinfile query in ansible to replace or delete a string

While trying to install apache via ansible I am getting the error of libToolt hence my apr-util is not getting configured. I am trying to replace $RM "cfgfile" with $RM -f "cfgfile" in configure by using regexp it is either getting copied at the last or not working.
- name: Replace file
path: file path
regexp: '$RM -f "cfgfile"'
But the value that is going when I am trying to run my YAML file is
$RM\\\"$cfgfile\"
You must escape the $ in your regexp since that character is meaningful to regexp; or, skip the silliness and just use line: instead of regexp: since your text does not contain any variable parts (which is the circumstances under which one would use a regex)

Multiline Template - string escaping in Ansible

I'm trying to get an effect similar to this article: https://gryzli.info/2017/12/21/ansible-debug-print-variables/
Which means in my case:
- name: Gather facts
vars:
msg: |
"{{ansible_distribution}}"
"{{ansible_distribution_major_version}}"
"{{ansible_distribution_release}}"
"{{ansible_distribution_version}}"
The problem ist that without quotes it throws an error to add the quotes. With quotes it throws the same error:
We could be wrong, but this one looks like it might be an issue with missing quotes. Always quote template expression brackets when theystart a value....
How do I correctly escape this multiline string so that Ansible can parse it? Or does this kind of code no longer work?
Q: "How do I correctly escape this multiline string so that Ansible can parse it?"
A: The problem is the indentation of the block. Quoting from Example 8.3. Invalid Block Scalar Indentation Indicators
ERROR:
A leading all-space line must not have too many spaces.
A following text line must not be less indented.
The text is less indented than the indicated level.
The correct syntax is (with or without quotation)
vars:
msg: |
"{{ansible_distribution}}"
"{{ansible_distribution_major_version}}"
"{{ansible_distribution_release}}"
"{{ansible_distribution_version}}"

Got an error message Syntax Error in ansible-playbook [duplicate]

This question already has answers here:
Quotes in ansible lineinfile
(4 answers)
Closed 4 years ago.
ERROR! Syntax Error while loading YAML.
did not find expected key
The error appears to have been in '/etc/ansible/main.yml': line 73, column 50, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- name: Ensure IP forwarding is disabled
shell: "sysctl net.ipv4.ip_forward ; grep "net\.ipv4\.ip_forward" /etc/sysctl.conf /etc/sysctl.d/*"
^ here
We could be wrong, but this one looks like it might be an issue with
unbalanced quotes. If starting a value with a quote, make sure the
line ends with the same set of quotes. For instance this arbitrary
example:
I using grep with "" into shell module in ansible playbook and got an ERROR message as follow "ERROR! Syntax Error while loading YAML."
- name: Ensure IP forwarding is disabled
shell: "sysctl net.ipv4.ip_forward ; grep "net\.ipv4\.ip_forward" /etc/sysctl.conf /etc/sysctl.d/*"
register: CIS_3.1.1
ignore_errors: True
That configuration file for ansible is in the YAML format and in YAML a scalar that represents a string can be in multiple formats:
plain: no quotes, has restrictions on the start character and internal character sequences, no escapes
single quoted: can contain double quotes, no escapes except for repeating single quotes
double quoted: backslash escapes in string, in string double quotes need to be escaped
literal: newlines are preserved, no escapes
folded: newlines are converted to spaces, no escapes
You are using double quoted style, and in that you would need to escape the internal double quotes (") and backslashes (\). That gets ugly and unreadble real soon. It is much more useful to use literal style in such cases:
- name: Ensure IP forwarding is disabled
shell: |-
sysctl net.ipv4.ip_forward ; grep "net\.ipv4\.ip_forward" /etc/sysctl.conf /etc/sysctl.d/*
I.e. you put |- (the minus is to strip the final newline of the following line), then put the line without starting or end quotes, indented, on the next line.

Resources