80

How can I test that stderr is non empty::

- name: Check script
  shell: . {{ venv_name }}/bin/activate && myscritp.py
  args:
    chdir: "{{ home }}"
  sudo_user: "{{ user }}"
  register: test_myscript

- debug: msg='myscritp is Ok'
  when: not test_myscript.stderr

So if there is no error I could read::

  TASK: [deploy | debug msg='critp is Ok] *******
  ok: [vagrant] => {
      "msg": "myscritp is Ok"
  }

In case the stderr is not empty a FATAl error occurs.

1

3 Answers 3

100

(ansible 2.9.6 ansible-lint 5.3.2)

See ansible-lint rules. The condition below results in error: 'empty-string-compare: Don't compare to empty string'

    when: test_myscript.stderr != ""

Correct syntax is

    when: test_myscript.stderr | length > 0

Quoting from source code

Use when: var|length > 0 rather than when: var != "" (or ' 'conversely when: var|length == 0 rather than when: var == "")


Notes

  1. Test empty bare variable e.g.
    - debug:
        msg: "Empty string '{{ var }}' evaluates to False"
      when: not var
      vars:
        var: ''

    - debug:
        msg: "Empty list {{ var }} evaluates to False"
      when: not var
      vars:
        var: []

give

  msg: Empty string '' evaluates to False
  msg: Empty list [] evaluates to False
  1. But, testing non-empty bare variable string depends on CONDITIONAL_BARE_VARS. Setting ANSIBLE_CONDITIONAL_BARE_VARS=false the condition works fine but setting ANSIBLE_CONDITIONAL_BARE_VARS=true the condition will fail
    - debug:
        msg: "String '{{ var }}' evaluates to True"
      when: var
      vars:
        var: 'abc'

gives

fatal: [localhost]: FAILED! => 
  msg: |-
    The conditional check 'var' failed. The error was: error while 
    evaluating conditional (var): 'abc' is undefined

Explicit cast to Boolean prevents the error but evaluates to False i.e. will be always skipped (unless var='True'). When the filter bool is used the options ANSIBLE_CONDITIONAL_BARE_VARS=true and ANSIBLE_CONDITIONAL_BARE_VARS=false have no effect

    - debug:
        msg: "String '{{ var }}' evaluates to True"
      when: var|bool
      vars:
        var: 'abc'

gives

skipping: [localhost]
  1. Quoting from Porting guide 2.8 Bare variables in conditionals
  - include_tasks: teardown.yml
    when: teardown

  - include_tasks: provision.yml
    when: not teardown

" based on a variable you define as a string (with quotation marks around it):"

  • In Ansible 2.7 and earlier, the two conditions above are evaluated as True and False respectively if teardown: 'true'

  • In Ansible 2.7 and earlier, both conditions were evaluated as False if teardown: 'false'

  • In Ansible 2.8 and later, you have the option of disabling conditional bare variables, so when: teardown always evaluates as True, and when: not teardown always evaluates as False when teardown is a non-empty string (including 'true' or 'false')

  1. Quoting from CONDITIONAL_BARE_VARS

Expect that this setting eventually will be deprecated after 2.12

4
  • 1
    This did not work for me. For me this : '{{ my_variable | length | int }} > 0' worked. PS: It gives me the warning [WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Commented Mar 19, 2019 at 10:24
  • 1
    @Raj: It's not enough to say "This did not work for me". Post the details and prove it. Follow How to create a Minimal, Complete, and Verifiable example. It's strange to propose wrong syntax instead. Commented Mar 19, 2019 at 11:36
  • @VladimirBotka I had a scenario where when: foo == '' and when: foo != ''was failing. Following your 'test bare variable' update worked for me. When I used when: foo and when: not foo I got the expected results. Great tip here. Commented Feb 12, 2021 at 4:31
  • I updated the answer with the current status. It's better to test the length instead of the implicit boolean. In 2.9.6, the evaluation of an empty string as a boolean works fine but the evaluation of a non-empty string depends on ANSIBLE_CONDITIONAL_BARE_VARS. It's a moving target. Test the length of the string to be on the safe side. Commented May 24, 2022 at 21:50
50

You can check for empty string (when stderr is empty)

- name: Check script
  shell: . {{ venv_name }}/bin/activate && myscritp.py
  args:
    chdir: "{{ home }}"
  sudo_user: "{{ user }}"
  register: test_myscript

- debug: msg='myscritp is Ok'
  when: test_myscript.stderr == ""

If you want to check for fail:

- debug: msg='myscritp has error: {{test_myscript.stderr}}'
  when: test_myscript.stderr != ""

Also look at this stackoverflow question

1
  • 19
    Ansible Galaxy Syntax Score: reports "E602: Don't compare to empty string". Commented Nov 18, 2018 at 12:37
15
when: myvar | default('', true) | trim != ''

I use | trim != '' to check if a variable has an empty value or not. I also always add the | default(..., true) check to catch when myvar is undefined too.

Not the answer you're looking for? Browse other questions tagged or ask your own question.