shell comand fails if returned value is 0

I’m using ansible 1.4.3 to install and update some RPM packages and I recently hit this bug. I’m using a pre_task on my playbook to check if there are any updates available for a specific package, like this:

  • name: check if there are updates available
    shell: yum list updates | grep “my-package” -c

register: num_updates
ignore_errors: true

  • debug: var=num_updates

The -c parameter on grep returns the number of lines in which “my-package” appears. If the number of lines is 0, then there are no updates available and I can skip a few steps down the road. The thing is the task fails with this output:

failed: [IP] => {“changed”: true, “cmd”: "yum list updates | grep "my-package" -c ", “delta”: “0:00:20.941810”, “end”: “2014-01-30 09:50:59.964388”, “rc”: 1, “start”: “2014-01-30 09:50:39.022578”}
stdout: 0

ok: [IP] => {
“num_updates”: {
“changed”: true,
“cmd”: "yum list updates | grep "my-package" -c ",
“delta”: “0:00:20.941810”,
“end”: “2014-01-30 09:50:59.964388”,
“invocation”: {
“module_args”: “yum list updates | grep "my-package" -c”,
“module_name”: “shell”
},
“rc”: 1,
“start”: “2014-01-30 09:50:39.022578”,
“stderr”: “”,
“stdout”: “0”,
“stdout_lines”: [
“0”
]
}
}

unless I add something like ‘| sed “s/^0$/‘0’/g”’ to the shell command, so that stdout turns into a string if the result is 0 and the output changes to:

changed: [IP] => {“changed”: true, “cmd”: "yum list updates | grep "my-package" -c | sed "s/^0$/‘0’/g" ", “delta”: “0:00:05.715204”, “end”: “2014-01-30 10:00:31.365116”, “rc”: 0, “start”: “2014-01-30 10:00:25.649912”, “stderr”: “”, “stdout”: “‘0’”}

ok: [IP] => {
“num_updates”: {
“changed”: true,
“cmd”: "yum list updates | grep "my-package" -c | sed "s/^0$/‘0’/g" ",
“delta”: “0:00:05.715204”,
“end”: “2014-01-30 10:00:31.365116”,
“invocation”: {
“module_args”: “yum list updates | grep "my-package" -c | sed "s/^0$/‘0’/g"”,
“module_name”: “shell”
},
“rc”: 0,
“start”: “2014-01-30 10:00:25.649912”,
“stderr”: “”,
“stdout”: “‘0’”,
“stdout_lines”: [
“‘0’”
]
}
}

Should I be doing something different?

You can control the failure state like this:

  • shell: foo
    register: bar
    failed_when: bar.rc == 17

Thank you, I hadn’t noticed you could control failure states like that.