使用Ansible命令行时遇通配符错误,如何解决及绕过通配符?
解决Ansible命令中的管道与通配符失效问题
咱们先拆解下你遇到的两个错误的根源:Ansible默认用command模块执行-a参数后的命令,而这个模块是直接调用系统exec执行命令,不会启动shell。这就导致管道|、通配符*这些shell专属的语法完全失效,被当成普通的命令参数传递给了对应程序——比如第一个命令里,df把|、grep、overf都当成了要检查的文件路径,自然会报错找不到;第二个命令里cat直接去找名为/etc/*release的文件,而非匹配所有release结尾的文件。
下面给你两种直接有效的解决方法:
方法一:改用shell模块(推荐)
shell模块会通过系统默认shell解析命令,所有shell语法都能正常工作。只需要在命令里加上-m shell参数即可:
修复第一个管道命令
ansible -i ansi slave62 -m shell -a 'df -Ph | grep -i overf'
(注:你原命令里all和slave62同时出现是冲突的,应该指定单个主机slave62或者all,上面命令已修正)
修复第二个通配符命令
ansible -i ansi slave61 -m shell -a "cat /etc/*release"
方法二:用sh -c包裹命令(兼容command模块)
如果因为某些原因必须用默认的command模块,可以把整个命令用sh -c(或bash -c)包裹,让shell来解析执行整个命令串:
修复管道命令
ansible -i ansi slave62 -a 'sh -c "df -Ph | grep -i overf"'
修复通配符命令
ansible -i ansi slave61 -a 'sh -c "cat /etc/*release"'
关于通配符的绕过/处理
本质上,通配符需要shell来展开,所以上面两种方法都是让shell参与命令解析的方案。如果不想依赖shell,也可以用Ansible的find模块先匹配文件,再通过with_items读取内容(适合Playbook场景),但对于ad-hoc命令来说,用shell模块是最直接高效的方式。
内容的提问来源于stack exchange,提问作者Rajesh Yidi




