Testing for a defined but non empty string

29,237 views
Skip to first unread message

Stephen Ryan

unread,
Jan 31, 2014, 6:58:17 AM1/31/14
to ansible...@googlegroups.com


Best to explain with an example

We have tasks setup like

- name: do something
  shell: do task
  when: foo is defined

This works perfectly for most situations however we have a number of places where we need to unset the variable to stop the command on certain hosts. Neither of the following work when set in the group vars and result in the task working.

foo:
foo: ""

So my question is how would one normally unset a variable like this or correctly test for it. Jinja docs suggest its just an "if variable" [1], so "when: foo" but that doesn't work whenever the variable has a value

fatal: [127.0.0.1] => error while evaluating conditional: foo

The closest I've gotten is
when: foo is defined and foo is string
but this feels wrong and there is no reference to using an "is string" check in the ansible docs.

[1] http://jinja.pocoo.org/docs/templates/#if

Nick Groenen

unread,
Jan 31, 2014, 7:29:11 AM1/31/14
to ansible...@googlegroups.com
If setting it to an empty string when you don't want it to run is okay
for your use case, you could do:

when: foo|default("") != ""

That will compare against the value of foo when it's defined, and
otherwise compare against an empty string.

--
Nick Groenen | zoni | @NickGroenen
https://zoni.nl | GnuPG/GPG key ID: 0xAB5382F6

Stephen Ryan

unread,
Jan 31, 2014, 7:46:06 AM1/31/14
to ansible...@googlegroups.com
Thanks, that will work in the case of foo: "". Before I go about switching all our templates, is there a way to also make it work in the case of foo: , i.e. without the empty string defined? Ansible detects these as None

Nick Groenen

unread,
Jan 31, 2014, 9:09:15 AM1/31/14
to ansible...@googlegroups.com
Yes, if Ansible sees that as None, then you could use |default(None) like this:

when: foo|default(None) != None

Adam Heath

unread,
Jan 31, 2014, 11:44:08 AM1/31/14
to ansible...@googlegroups.com
foo is defined and foo !+ "" or "default-value"
> --
> 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.
> To post to this group, send email to ansible...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

Jialiang Liang

unread,
Apr 7, 2015, 3:54:01 AM4/7/15
to ansible...@googlegroups.com
I faced the same problem. 

I tried Nick Groenen's code and it doesn't work when the params is like this:
```
foo:
```
in this case, foo is define and foo == none

And it doesn't work when foo: '   '

This is what I came up with:

not((foo is undefined) or (foo is none) or (foo|trim == ''))

Not sure if there is any build-in function that implement similar logic.

Cheers

Leo Liang

在 2014年1月31日星期五 UTC+11下午10:58:17,Stephen Ryan写道:

Arbab Nazar

unread,
Dec 27, 2015, 8:31:58 AM12/27/15
to Ansible Project
@ Leo  Thanks, this work for me as well

einarc

unread,
Jun 3, 2016, 9:44:43 PM6/3/16
to Ansible Project, ni...@travelbird.nl
Why is this not in the documentation for conditionals? it should be basic stuff!!!

einarc

unread,
Jun 3, 2016, 9:46:49 PM6/3/16
to Ansible Project
Tell me about it Leo, the documentation on this language is seriously lacking.

Michael Shi

unread,
Jan 26, 2017, 2:50:39 AM1/26/17
to Ansible Project
Is there really no better way to do it? While Leo's method works it's extremely ugly to look at nor easily reusable.

Johannes Kastl

unread,
Jan 26, 2017, 3:01:04 AM1/26/17
to ansible...@googlegroups.com
On 26.01.17 08:50 Michael Shi wrote:
> On Friday, 31 January 2014 22:58:17 UTC+11, Stephen Ryan wrote:
>> This works perfectly for most situations however we have a number
>> of places where we need to unset the variable to stop the command
>> on certain hosts. Neither of the following work when set in the
>> group vars and result in the task working.
>>
>> foo:
>> foo: ""

I think the iptables rule that I found on galaxy uses the following to
set a variable to empty:

foo: {}

Maybe this works in your case, too?

Johannes

signature.asc

Jinesh Choksi

unread,
Jan 26, 2017, 10:53:45 AM1/26/17
to Ansible Project

On Thursday, 26 January 2017 07:50:39 UTC, Michael Shi wrote:
Is there really no better way to do it? While Leo's method works it's extremely ugly to look at nor easily reusable. 

Would this help you?

- name: do something
  shell: do task
  when: ansible_local[foo] is defined

Instead of using ansible_local (which holds local facts), you could also use:

vars
hostvars

both of them are dictionaries with key/value pairs.


Reply all
Reply to author
Forward
0 new messages