我想在临时的 Ansible 命令中运行一个 sub shell 命令。
这是我想做的:
sudo ansible myservers -m shell -a "touch /var/tmp/$(uname -n)"
它创建远程文件,但使用本地主机的名称,它不会在远程服务器上执行 uname 命令。
我找到了解决方案:
sudo ansible myservers -m shell -a '/bin/bash -c "toto=`uname -n` ; touch /var/tmp/$toto.json;"'
似乎我必须启动一个 shell 才能执行子 shell 命令,但它有效。
问题来自命令中的双引号。 它们意味着双引号(包括您的$(...)
)之间的内容将由执行此命令的 shell(您的 Ansible 控制节点)解释,因此您可以获得 ansible 控制节点名称。
如果将双引号替换为简单引号,则控制节点的 shell 将不会解释内容,而是将其"按原样"传递给 ansible 主机。之后,这些 ansible 主机将解释$(...)
,因此您将获得目标 ansible 主机名。
请参阅 http://www.gnu.org/software/bash/manual/html_node/Single-Quotes.html 和 https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html
所以它可以通过以下方式修复:
ansible myservers -m shell -a 'touch /var/tmp/$(uname -n)'
(我不明白你为什么要使用sudo
)
或者(如果清单中的主机名称足够好),您可以使用:
ansible myservers -m shell -a 'touch /var/tmp/{{ inventory_hostname }}'
顺便说一句,如果您最终在剧本中使用此命令,另一种解决方案是使用 Ansible 事实 : 例如ansible_hostname
或ansible_fqdn