为何bash快捷命令不支持ansible-playbook的--limit通配符*?
问题分析与解决:bash快捷命令中Ansible通配符失效的原因
为什么会匹配到zip文件?
当你执行pre BBCC*时,Bash的路径扩展(Globbing)机制先起作用:它会在你当前的工作目录下,查找所有以BBCC开头的文件,把BBCC*替换成这些文件名的列表(比如你看到的BBCC01.zip、BBCC_.zip),再把这个列表传给pre函数。
而你直接在目标目录执行ansible-playbook run_pre_check.yml --limit 'BBCC*'时,单引号阻止了Bash的路径扩展,BBCC*会原封不动传给Ansible,由Ansible自己去匹配主机清单里的主机名。
快捷命令的写法问题
你的pre函数只用$1接收参数,但当Bash把BBCC*扩展成多个文件名后,$1只会取第一个文件名,剩下的文件名会被当成ansible-playbook的额外命令行参数,这就是报错提示“unrecognized arguments”的原因。
解决方法
方法1:修改函数,支持完整参数传递
把函数改成以下形式,确保所有传入的参数作为一个整体传给Ansible的--limit选项:
# precheck shortcut # to run, type "pre <whatever your limits will be>" pre (){ # 切换目录失败则退出,避免后续命令执行错误 cd ~/myrepos/pre-post-role || return # "$*" 将所有参数合并为一个字符串传递 ansible-playbook run_pre_check.yml --limit "$*" # 回到之前的工作目录,比cd更合理 cd - > /dev/null }
调用时可以直接用pre BBCC*,不过如果当前目录有匹配的文件,Bash还是会先扩展,所以更稳妥的方式是用单引号包裹通配符:pre 'BBCC*',确保BBCC*原封不动传给Ansible。
方法2:调用时用单引号包裹通配符
不修改函数的情况下,调用时给通配符加上单引号:
pre 'BBCC*'
单引号会阻止Bash的路径扩展,BBCC*会直接作为$1的值传给函数,由Ansible处理主机匹配。
核心原理补充
- Bash在执行命令前,会先对命令行中的通配符、变量等进行解析扩展,再执行命令;
- 引号(单引号/双引号)可以阻止这种扩展:单引号完全屏蔽所有扩展,双引号会保留变量扩展但阻止路径扩展;
- Ansible的
--limit参数支持的通配符,是由Ansible自己解析的,不是Bash的路径扩展,所以需要让BBCC*原封不动到达Ansible。
内容的提问来源于stack exchange,提问作者nextmick
相关产品推荐
相关产品推荐

