# Testing for a defined but non empty string

**URL:** <https://forum.ansible.com/t/testing-for-a-defined-but-non-empty-string/14467>\
**Category:** Ansible Project\
**Created:** [January 31, 2014, 11:58am UTC](https://forum.ansible.com/t/testing-for-a-defined-but-non-empty-string/14467 "2014-01-31T11:58:17Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Stephen\_Ryan](https://avatars.discourse-cdn.com/v4/letter/s/ac91a4/32.png) [@Stephen\_Ryan](https://forum.ansible.com/u/Stephen_Ryan)\
**Post date:** [January 31, 2014, 11:58am UTC](https://forum.ansible.com/t/testing-for-a-defined-but-non-empty-string/14467/1 "2014-01-31T11:58:17Z")

</div>

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](http://jinja.pocoo.org/docs/templates/#if)

---

<div class="post-metadata">

**Author:** ![Nick\_Groenen](https://avatars.discourse-cdn.com/v4/letter/n/c77e96/32.png) [@Nick\_Groenen](https://forum.ansible.com/u/Nick_Groenen)\
**Post date:** [January 31, 2014, 12:29pm UTC](https://forum.ansible.com/t/testing-for-a-defined-but-non-empty-string/14467/2 "2014-01-31T12:29:11Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Stephen\_Ryan](https://avatars.discourse-cdn.com/v4/letter/s/ac91a4/32.png) [@Stephen\_Ryan](https://forum.ansible.com/u/Stephen_Ryan)\
**Post date:** [January 31, 2014, 12:46pm UTC](https://forum.ansible.com/t/testing-for-a-defined-but-non-empty-string/14467/3 "2014-01-31T12:46:06Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Nick\_Groenen](https://avatars.discourse-cdn.com/v4/letter/n/c77e96/32.png) [@Nick\_Groenen](https://forum.ansible.com/u/Nick_Groenen)\
**Post date:** [January 31, 2014, 2:09pm UTC](https://forum.ansible.com/t/testing-for-a-defined-but-non-empty-string/14467/4 "2014-01-31T14:09:15Z")

</div>

Yes, if Ansible sees that as None, then you could use |default(None) like this:

when: foo|default(None) != None

---

<div class="post-metadata">

**Author:** ![adam2](https://avatars.discourse-cdn.com/v4/letter/a/ecae2f/32.png) [@adam2](https://forum.ansible.com/u/adam2)\
**Post date:** [January 31, 2014, 4:44pm UTC](https://forum.ansible.com/t/testing-for-a-defined-but-non-empty-string/14467/5 "2014-01-31T16:44:08Z")

</div>

foo is defined and foo !+ "" or "default-value"

---

<div class="post-metadata">

**Author:** ![Jialiang\_Liang](https://avatars.discourse-cdn.com/v4/letter/j/d9b06d/32.png) [@Jialiang\_Liang](https://forum.ansible.com/u/Jialiang_Liang)\
**Post date:** [April 7, 2015, 7:54am UTC](https://forum.ansible.com/t/testing-for-a-defined-but-non-empty-string/14467/6 "2015-04-07T07:54:01Z")

</div>

I faced the same problem.

I tried Nick Groenen’s code and it doesn’t work when the params is like this:

```auto
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写道：

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/ansible/original/1X/1882d9a01da5d8996a862359b0913cc568a39b84.svg) [@system](https://forum.ansible.com/u/system)\
**Post date:** [December 27, 2015, 1:31pm UTC](https://forum.ansible.com/t/testing-for-a-defined-but-non-empty-string/14467/7 "2015-12-27T13:31:57Z")

</div>

@ Leo Thanks, this work for me as well

---

<div class="post-metadata">

**Author:** ![ecoutin\_boingo](https://avatars.discourse-cdn.com/v4/letter/e/ac91a4/32.png) [@ecoutin\_boingo](https://forum.ansible.com/u/ecoutin_boingo)\
**Post date:** [June 4, 2016, 1:44am UTC](https://forum.ansible.com/t/testing-for-a-defined-but-non-empty-string/14467/8 "2016-06-04T01:44:42Z")

</div>

Why is this not in the documentation for conditionals? it should be basic stuff!!!

---

<div class="post-metadata">

**Author:** ![ecoutin\_boingo](https://avatars.discourse-cdn.com/v4/letter/e/ac91a4/32.png) [@ecoutin\_boingo](https://forum.ansible.com/u/ecoutin_boingo)\
**Post date:** [June 4, 2016, 1:46am UTC](https://forum.ansible.com/t/testing-for-a-defined-but-non-empty-string/14467/9 "2016-06-04T01:46:49Z")

</div>

Tell me about it Leo, the documentation on this language is seriously lacking.

---

<div class="post-metadata">

**Author:** ![Michael\_Shi](https://avatars.discourse-cdn.com/v4/letter/m/34f0e0/32.png) [@Michael\_Shi](https://forum.ansible.com/u/Michael_Shi)\
**Post date:** [January 26, 2017, 7:50am UTC](https://forum.ansible.com/t/testing-for-a-defined-but-non-empty-string/14467/10 "2017-01-26T07:50:39Z")

</div>

Is there really no better way to do it? While Leo’s method works it’s extremely ugly to look at nor easily reusable.

---

<div class="post-metadata">

**Author:** ![Johannes\_Kastl](https://avatars.discourse-cdn.com/v4/letter/j/bbe5ce/32.png) [@Johannes\_Kastl](https://forum.ansible.com/u/Johannes_Kastl)\
**Post date:** [January 26, 2017, 8:00am UTC](https://forum.ansible.com/t/testing-for-a-defined-but-non-empty-string/14467/11 "2017-01-26T08:00:48Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Jinesh\_Choksi](https://avatars.discourse-cdn.com/v4/letter/j/a6a055/32.png) [@Jinesh\_Choksi](https://forum.ansible.com/u/Jinesh_Choksi)\
**Post date:** [January 26, 2017, 3:53pm UTC](https://forum.ansible.com/t/testing-for-a-defined-but-non-empty-string/14467/12 "2017-01-26T15:53:45Z")

</div>

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.

More info - [http://docs.ansible.com/ansible/playbooks\_variables.html](http://docs.ansible.com/ansible/playbooks_variables.html)
