为何Ansible判定该shell命令返回非零退出码?
问题:Ansible中执行带
|| echo的pkill命令报错,命令行执行却正常 我编写了如下Ansible任务:
- name: Kill usr/bin/perl -w /usr/share/debconf/frontend shell: "{{ item }}" with_items: - 'pkill -9 -f debconf/frontend || echo' changed_when: false # Don't report changed state
在命令行直接执行该shell命令时,借助|| echo能确保返回0退出码:
~$ pkill -9 -f debconf/frontend || echo ~$ echo $? 0
但在Ansible中运行时却报错:
failed: [testhost1] (item=pkill -9 -f debconf/frontend || echo) => {"ansible_loop_var": "item", "changed": false, "cmd": "pkill -9 -f debconf/frontend || echo", "delta": "0:00:00.132296", "end": "2023-01-13 10:34:11.098765", "item": "sudo pkill -9 -f debconf/frontend || echo", "msg": "non-zero return code", "rc": -9, "start": "2023-01-13 10:34:10.966469", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
请问哪里操作有误?
原因与解决办法
问题原因
当Ansible以sudo方式执行pkill -9 -f debconf/frontend时,pkill的-f参数会匹配所有命令行包含debconf/frontend的进程——包括当前正在运行的sudo pkill -9 -f debconf/frontend进程本身。pkill会直接杀死这个自身进程,导致整个命令被SIGKILL信号强制终止,退出码为-9。这种情况下|| echo根本无法触发(因为进程不是正常返回非0退出码,而是被信号终止),所以Ansible判定任务执行失败。
解决办法
方法一:用正则技巧避免pkill自匹配
把命令改成以下形式,利用正则匹配的特性避免pkill匹配自身进程:
- name: Kill usr/bin/perl -w /usr/share/debconf/frontend shell: "{{ item }}" with_items: - 'pkill -9 -f "[d]ebconf/frontend" || echo' changed_when: false # Don't report changed state
这里[d]ebconf是正则表达式,会匹配目标进程的debconf字符串,但当前执行的命令行里是[d]ebconf,不会被该正则匹配到,因此pkill只会杀死目标进程,不会自杀。如果没有匹配到目标进程,命令会正常返回非0码,此时|| echo会触发,确保退出码为0,Ansible就不会报错。
方法二:精确匹配目标进程命令行
如果明确知道目标进程的完整命令行,可以用更精确的匹配规则,避免误匹配:
- name: Kill usr/bin/perl -w /usr/share/debconf/frontend shell: "{{ item }}" with_items: - 'pkill -9 -f "^/usr/bin/perl -w /usr/share/debconf/frontend" || echo' changed_when: false # Don't report changed state
^符号表示匹配命令行开头,这样只会匹配以目标命令开头的进程,不会匹配到sudo执行的pkill命令。
内容的提问来源于stack exchange,提问作者Roman Gaufman
相关产品推荐
相关产品推荐

