Ansible临时命令中执行子Shell命令的问题求助
解决Ansible临时命令中远程命令替换被本地解析的问题
这个问题我太熟悉了!你遇到的核心问题是本地Shell提前执行了命令替换:当你用双引号包裹-a参数时,你的本地Shell会先把$(uname -n)解析成你当前机器的主机名,然后才把已经替换好的命令发送给远程服务器执行——这就是为什么远程创建的文件名是本地主机名,而不是远程服务器的。
下面给你三种可行的解决办法:
方法一:用单引号包裹命令参数(最直接)
单引号在Shell中会阻止所有变量和命令替换操作,让整个命令原封不动地传递给远程服务器,由远程Shell来解析执行uname -n:sudo ansible myservers -m shell -a 'touch /var/tmp/$(uname -n)'方法二:使用Ansible内置事实变量(更符合Ansible最佳实践)
Ansible在连接远程主机时会自动收集主机的事实信息,其中就包含远程主机的主机名ansible_hostname,直接用这个变量更可靠,不需要在远程执行额外的命令:sudo ansible myservers -m shell -a "touch /var/tmp/{{ ansible_hostname }}"这里双引号是安全的,因为Ansible会优先解析自己的模板变量,再将最终命令发送到远程。
方法三:转义$符号(适合必须用双引号的场景)
如果你因为某些原因必须使用双引号,可以通过转义$符号来阻止本地Shell解析命令替换:sudo ansible myservers -m shell -a "touch /var/tmp/\$(uname -n)"转义后的
\$会被本地Shell原样传递到远程,远程Shell执行时就会正确解析$(uname -n)了。
内容的提问来源于stack exchange,提问作者tonio94
相关产品推荐
相关产品推荐

