与所有其他答案和评论相反,使用 script
模块存在一些缺点,特别是在远程(而非本地)主机上运行时。以下摘自 官方 ansible 文档 的片段:
通常最好编写 Ansible 模块而不是推送脚本。将脚本转换为 Ansible 模块以获得奖励分数!
ssh 连接插件将通过 -tt 强制伪终端分配执行脚本。伪终端没有 stderr 通道,所有 stderr 都发送到 stdout。如果您依赖于分离的 stdout 和 stderr 结果键,请改用一组复制 + 命令任务,而不是使用脚本。
如果本地脚本的路径包含空格,则需要引用。
此模块也支持 Windows 目标。
例如,对于任何不是 localhost 的主机,使用 script
模块运行此脚本,并注意脚本的 stdout
和 stderr
。
#!/bin/bash
echo "Hello from the script"
nonoexistingcommand
echo "hello again"
你会得到类似下面的东西;注意
stdout
已经合并了所有的
stderr
。(理想情况下,
line 6: nonoexistingcommand: command not found
应该在
stderr
中)因此,如果你正在脚本输出的
stdout
中搜索某些子字符串,你可能会得到不正确的结果。
ok: [192.168.122.83] => {
"script_out": {
"changed": true,
"failed": false,
"rc": 0,
"stderr": "Shared connection to 192.168.122.83 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.122.83 closed."
],
"stdout": "Hello from the script\r\n/home/ps/.ansible/tmp/ansible-tmp-1660578527.4335434-35162-230921807808160/my_script.sh: line 6: nonoexistingcommand: command not found\r\nhello again\r\n",
"stdout_lines": [
"Hello from the script",
"/home/ps/.ansible/tmp/ansible-tmp-1660578527.4335434-35162-230921807808160/my_script.sh: line 6: nonoexistingcommand: command not found",
"hello again"
]
}
}
文档不鼓励用户使用脚本模块;考虑将您的脚本转换为Ansible模块;这里有一篇由我撰写的simple post,解释如何将您的脚本转换为Ansible模块。
此外,如果您计划在脚本模块中使用async/poll
,则不支持;请查看this。
还有其他重要原因,但不限于:
如果您用Python编写模块,可以使用Ansible Module
提供的大量功能。例如,您可以通过在模块中设置changed_when
变量来设置幂等性(请参见@DanOPT的评论)。
您可以在模块内安全地使用敏感变量,并通过为特定变量设置no_log
来保持其安全性。如果您不使用模块,则需要自行负责确保敏感变量不会被记录到日志和stdout中。例如:
password=dict(type='str',
required=True,
no_log=True)