Escaping $ inside a variable

5,713 views
Skip to first unread message

Jānis Ģeņģeris

unread,
Oct 19, 2012, 5:08:17 PM10/19/12
to ansible...@googlegroups.com
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.

Thanks,
--janis

Claus Strommer

unread,
Oct 19, 2012, 6:06:07 PM10/19/12
to ansible...@googlegroups.com
You're probably wanting a double backslash. Or triple, I can never
remember which.
> --
>
>

Daniel Hokka Zakrisson

unread,
Oct 19, 2012, 6:23:54 PM10/19/12
to ansible...@googlegroups.com
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

Jānis Ģeņģeris

unread,
Oct 20, 2012, 5:17:42 AM10/20/12
to ansible...@googlegroups.com, dan...@hozac.com
Somehow this is not working for me.

Using this:
    - net_status_match_02: "^[[:blank:]]+address ${service_net_ip}$"

I get this error:
Traceback (most recent call last):
  File "/home/j9/software/ansible/bin/ansible-playbook", line 164, in <module>
    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: "^[[:blank:]]+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: "^[[:blank:]]+address ${service_net_ip}\$"
                                                                   ^

Michael DeHaan

unread,
Oct 20, 2012, 7:26:16 AM10/20/12
to ansible...@googlegroups.com
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
> --
>
>

Kesten Broughton

unread,
Dec 10, 2013, 4:48:12 PM12/10/13
to ansible...@googlegroups.com
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

Kahlil Hodgson

unread,
Dec 10, 2013, 5:03:51 PM12/10/13
to ansible...@googlegroups.com

On 11 December 2013 08:48, Kesten Broughton <solarmobi...@gmail.com> wrote:
path_to_git_extras: 'PATH=\\$PATH:\\$ANSIBLE_21CT_HOME/roles/git/files'

does '>' quoting help?

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

K

kesten broughton

unread,
Dec 11, 2013, 1:13:43 PM12/11/13
to ansible...@googlegroups.com
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

Kahlil Hodgson

unread,
Dec 11, 2013, 4:28:44 PM12/11/13
to ansible...@googlegroups.com
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
> --
> You received this message because you are subscribed to the Google Groups
> "Ansible Project" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to ansible-proje...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

kesten broughton

unread,
Dec 11, 2013, 5:28:50 PM12/11/13
to ansible...@googlegroups.com
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?


You received this message because you are subscribed to a topic in the Google Groups "Ansible Project" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ansible-project/7IBnFvz1eow/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ansible-proje...@googlegroups.com.

Michael DeHaan

unread,
Dec 11, 2013, 6:01:31 PM12/11/13
to ansible...@googlegroups.com
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.





Michael DeHaan <mic...@ansibleworks.com>
CTO, AnsibleWorks, Inc.
http://www.ansibleworks.com/

Reply all
Reply to author
Forward
0 new messages