Escaping $ inside a variable

I have variable defined in playbook like this:

vars:

  • net_status_match_02: “[1]+address ${service_net_ip}$”

How to properly escape the ‘$’ sign? The backslash is not working for me.

Thanks,
–janis


  1. [:blank:] ↩︎

You're probably wanting a double backslash. Or triple, I can never remember which.

Jānis Ģeņģeris wrote:

I have variable defined in playbook like this:

vars:
   - net_status_match_02: "^[[:blank:]]+address ${service_net_ip}\$"

How to properly escape the '$' sign? The backslash is not working for me.

That depends entirely on what you want to do with it. Ansible's variable
replacer will not touch any $ that is not followed by a valid variable name.

Daniel

Somehow this is not working for me.

Using this:

  • net_status_match_02: “[1]+address ${service_net_ip}$”

I get this error:

Traceback (most recent call last):
File “/home/j9/software/ansible/bin/ansible-playbook”, line 164, in
sys.exit(main(sys.argv[1:]))
File “/home/j9/software/ansible/bin/ansible-playbook”, line 135, in main
pb.run()
File “/home/j9/software/ansible/lib/ansible/playbook/init.py”, line 170, in run
play = Play(self, play_ds, play_basedir)
File “/home/j9/software/ansible/lib/ansible/playbook/play.py”, line 83, in init
self._tasks = self._load_tasks(self._ds, ‘tasks’)
File “/home/j9/software/ansible/lib/ansible/playbook/play.py”, line 123, in _load_tasks
results.append(Task(self,x,module_vars=task_vars))
File “/home/j9/software/ansible/lib/ansible/playbook/task.py”, line 142, in init
self.action = utils.template(None, self.action, self.module_vars)
File “/home/j9/software/ansible/lib/ansible/utils.py”, line 390, in template
text = varReplace(unicode(text), vars, expand_lists=expand_lists)
File “/home/j9/software/ansible/lib/ansible/utils.py”, line 309, in varReplace
replacement = varReplace(replacement, vars, depth=depth+1, expand_lists=expand_lists)
File “/home/j9/software/ansible/lib/ansible/utils.py”, line 296, in varReplace
m = _varFind(raw)
File “/home/j9/software/ansible/lib/ansible/utils.py”, line 249, in _varFind
if text[var_start] == ‘{’:
IndexError: string index out of range

When using backslash escape:

  • net_status_match_02: “[2]+address ${service_net_ip}$”

This error:

ERROR: Syntax Error while loading YAML script, /home/j9/cfg/ansible/playbooks/network_config.yml
Note: The error may actually appear before this position: line 31, column 68

  • net_status_match_02: “[3]+address ${service_net_ip}$”
    ^

  1. [:blank:] ↩︎

  2. [:blank:] ↩︎

  3. [:blank:] ↩︎

Hi Jānis,

Please make sure there's a bug filed in github for this. It looks
like we need to improve the string replacement code. If you can paste
as much of your playbook as possible into the ticket that would be
great.

(You will probably have to indent each line in github by four spaces
to get it to render correctly in the browser.)

http://github.com/ansible/ansible, click on "issues".

your problem *MAY* go away if you change that to $service_net_ip, but
I can't be positive without trying it. In any event, paste the full
playbook, redacting what you need to, and we can take a look.

--Michael

Is there a solution to this?

I am trying to add to PATH and can’t keep ansible from evaluating a $
I’ve tried ‘$’ and several other things.

I’m trying to achieve the following:

MYPATH is an env variable on a remote host.

I want to add a string defined in vars/main.yml to a line in .bash_profile

export PATH=$PATH:$MYPATH

In full detail here

  • name: Add git scripts to .bash_profile
    lineinfile: dest=“{{home_prefix}}/{{ansible_ssh_user}}/.bash_profile”
    regexp=“{{item.regexp}}”
    line=“{{item.line}}”
    with_items:
  • {
    regexp: “roles/git/files”,
    line: ‘{{path_to_git_extras}}’
    }

with path_to_git_extras defined in vars/main.yml

path_to_git_extras: ‘PATH=\$PATH:\$ANSIBLE_21CT_HOME/roles/git/files’

I thought jinja filters might work here but i get variable “string” undefined

path_to_git_extras: ‘{{string(“export PATH=$PATH:$ANSIBLE_21CT_HOME/roles/git/files”)}}’

The latter is what i really want. A function or something that says “Don’t evaluate anything inside here EVER”

I didn’t see an issue on git. Still want one filed?

kesten

does '>' quoting help?

    path_to_git_extras: >
        PATH=$PATH:$ANSIBLE_21CT_HOME/roles/git/files

K

unfortunately no.

with
path_to_git_extras: >
PATH=$PATH:$ANSIBLE_21CT_HOME/roles/git/files

when the file gets templated to the remote, it contains the value of ANSIBLE_21CT_HOME evaluated on the local machine. The remote has the correct ANSIBLE_21CT_HOME path but it never gets a chance.

I tried something new with jinja2 templating which i was sure would work but it seems that ansible $variable substitution happens in a peculiar way.

I tried this in my file template, but still get the local $ANSIBLE_21CT_HOME evaluated.

TEST 1
{% filter string %}
export PATH=“$PATH:$ANSIBLE_21CT_HOME/roles/git/files”
{% endfilter %}

TEST2
Testing with upper, i see the export line uppercased except for the $ANSIBLE_21CT_HOME portion.

{% filter upper %}
export PATH=“$PATH:$ANSIBLE_21CT_HOME/roles/git/files”
{% endfilter %}

Result
EXPORT PATH=“$PATH:/Users/kbroughton/21ct-ansible/ROLES/GIT/FILES”

So it seems that in TEST2 that the jinja2 filter gets applied BEFORE the ansible variable substitution,
but it appears that in TEST1 the jinja2 filter comes after, or is not being applied somehow.

Peculiar.

kesten

How about the following:

    path_to_git_extras: "{{ 'EXPORT PATH=$' + 'PATH:' + '$' +
'ANSIBLE_21CT_HOME/roles/git/file' }}"

Or something similar in a template.

The problem will probably just go away once the old style '$' variable
syntax is retired.

K

Kahlil (Kal) Hodgson GPG: C9A02289
Head of Technology (m) +61 (0) 4 2573 0382
DealMax Pty Ltd (w) +61 (0) 3 9008 5281

Suite 1415
401 Docklands Drive
Docklands VIC 3008 Australia

"All parts should go together without forcing. You must remember that
the parts you are reassembling were disassembled by you. Therefore,
if you can't get them together again, there must be a reason. By all
means, do not use a hammer." -- IBM maintenance manual, 1925

Amazingly no! ansible catenates the strings, then evaluates it with the local variable.

I wonder if there is an option that can be set that will allow the new behavior - {{ only with no $ vars - that can be used for now?

Pretty sure this isn’t going through the local shell before getting to the git module.

You can debug with setting ANSIBLE_KEEP_REMOTE_FILES=1 in the environment and running with -vvv and looking at that module it outputs on the remote system.

If you see that behavior, please file a ticket if you are seeing this on Ansible 1.4.X or higher.