Ansible从stdout行提取子串返回空字符串问题排查与解决
Ansible中正确遍历stdout_lines并提取Docker服务信息的解决方法
我之前也碰到过这个Ansible的坑,正好能帮你解决!你想要在Ansible里获取特定节点的Docker服务列表,用shell模块模拟输出后注册结果,再通过正则提取子串,但遇到了item=None或者输出错误字符串的问题,对吧?
问题场景
你的初始任务代码是这样的:
--- - name: echo text (this will later be docker stack ps SERVICE instead of echo) shell: echo 'SomePrefix_value1.1\nSomePrefix_value2.1' register: result - name: Print values debug: msg: '{{ item | regex_search(regexp) }}' with_items: result.stdout_lines vars: regexp: 'SomePrefix_([^\.]+)'
执行后要么输出空字符串(调试显示item=None),把正则改成'.*'后,输出的居然是字符串result.stdout_lines而不是实际的每一行内容。
问题根源
这是Ansible变量解析的常见小坑:当你在with_items后面直接写变量名而不用{{ }}包裹时,Ansible不会将其解析为你注册的变量,而是把它当作普通字符串处理。也就是说你根本不是在遍历result.stdout_lines这个列表,而是在处理字符串"result.stdout_lines"本身,自然会出现异常输出。
解决方法
只需要给result.stdout_lines加上变量插值的包裹,让Ansible正确识别这是一个变量即可:
--- - name: echo text (this will later be docker stack ps SERVICE instead of echo) shell: echo 'SomePrefix_value1.1\nSomePrefix_value2.1' register: result - name: Print values debug: msg: '{{ item | regex_search(regexp, '\1') }}' # 加'\1'可直接提取正则捕获组内容 with_items: '{{ result.stdout_lines }}' vars: regexp: 'SomePrefix_([^\.]+)'
这里额外提个小技巧:如果想直接拿到正则里的捕获组内容(比如value1、value2),可以在regex_search后面加上第二个参数'\1',不用再做二次处理。
后续替换Docker命令的小提示
等你把模拟的echo命令换成实际的Docker命令(比如docker stack ps SERVICE --format "{{.Name}}"这类格式化输出命令)时,记得先在目标节点上验证Docker命令的输出格式,确保和你的正则规则匹配,这样提取出来的服务信息才会准确。
内容的提问来源于stack exchange,提问作者Yannic Bürgmann
相关产品推荐
相关产品推荐

