如何使用Ansible(ansibleshell模块)

如何使用Ansible(ansibleshell模块)

浏览次数:
信息来源: 用户投稿
更新日期: 2026-04-30
文章简介

Ansible核心为几乎所有用例提供了数百个Ansible模块。您可以在Ansible文档页面上找到所有Ansible模块的完整列表及其描述。有时,您只需要像在bashshell上一样直接在目标主机上

2025阿里云双十一服务器活动

Ansible核心为几乎所有用例提供了数百个Ansible模块。您可以在Ansible文档页面上找到所有Ansible模块的完整列表及其描述。有时,您只需要像在bashshell上一样直接在目标主机上执行命令。这就是Ansibleshell模块派上用场的地方。在本指南中,您将了解Ansibleshell模块、它的工作原理以及如何使用它对托管节点执行命令。

Ansibleshell模块是一个方便的模块,它允许您直接在远程目标的shell上执行命令,就像您已登录一样。这样做有助于保持命令执行的原创性。

shell模块与命令模块密切相关。两者都有助于实现相同的结果。两者之间存在一些差异:

  • shell模块直接在目标主机的shell上执行命令。默认情况下,shell模块使用/bin/shshell来运行命令,尽管您可以将其配置为使用其他shell。使用command模块,执行的命令不通过shell处理。
  • 由于命令不在shell上执行,命令模块不支持环境变量、管道和其他运算符,例如'>'、'<'、'&'、';'?和'|?|'。使用shell模块,完全支持管道、重定向和变量。因此,shell模块提供了更大的灵活性。
  • 如果在目标系统上安全地运行命令是您的首要任务,请使用命令模块。与shell模块不同,command模块不影响远程用户的shell环境。
  • AnsibleShell模块与其他模块

    commandAnsibleshell模块与、script和模块属于同一类别raw。这些统称为运行命令。

    虽然可以快速高效地完成任务,但运行命令只能作为最后的手段使用。这是因为它们在执行任务时应用最少的逻辑,并且不存在所需状态的概念。如果已经满足导致错误的条件,则shell命令的后续执行可能会失败。

    此外,除非您注册第一个命令的结果,否则无法使用shell模块捕获错误。然后,您必须在剧本中执行后续任务以实施条件逻辑来确认错误是否发生,然后进行处理。这可能会导致严重破坏自动化的瓶颈。

    出于这个原因,shell命令应该仅限于在远程系统上执行简单的任务。如果需要服务或应用程序的理想状态,建议使用特定于任务的模块,例如service、copy、file和lineinfile,仅举几例。这使得剧本更加通用和可重用。

  • 一个Ansible控制节点。在本教程中,我们运行的是Ubuntu20.04。如果您还没有安装Ansible,请按照我们关于如何在Ubuntu20.04上安装和配置Ansible的指南进行操作。
  • 您将对其运行命令的远程主机。
  • 运行AnsibleAd-hocShell命令

    Ansible的真正力量在于剧本。剧本用于在目标主机上执行复杂的任务。假设您想要非常快速地运行命令而不保存它们供以后使用。你会怎么做?这就是临时命令派上用场的地方。

    Ad-hoc命令是单行命令,您无需编写剧本即可即时运行。

    例如,您可能想要检查远程主机的正常运行时间或磁盘空间利用率。与其为此类任务编写完整的剧本,更好的方法是对您的主机运行临时命令。

    ansible[pattern]-m[MODULE]-a{COMMAND_OPTIONS}

    该模式指定目标主机所属的主机组。该-m选项指定模块的类型,而该-a选项采用命令参数。

    要检查所有目标主机的正常运行时间,请运行以下命令:

    sudoansibleall-mshell-a'uptime-p'

    要检查内存使用情况,请运行:

    sudoansibleall-mshell-a'free-m'

    查看db_server组下主机的磁盘空间利用率,执行:

    sudoansibledb_server-mshell-a'df-Th'

    使用AnsibleShell模块运行单个命令

    除了运行临时命令外,Ansibleshell模块还用于playbook以指定要在远程主机上执行的任务。

    -name:Shellmoduleexample

    -name:Checksysteminformation

    msg:"{{os_info.stdout_lines}}"

    在此示例中,剧本针对名为webservers的主机组运行,并执行一个lsb_release-a命令来检索有关操作系统版本的详细信息。然后将输出保存在一个名为的寄存器变量中os_info。

    最后一行使用模块将存储在os_info变量中的输出打印到标准输出。debug

    如果文件不存在,则使用Shell模块运行命令

    该creates参数允许您在文件不存在时运行命令。它指定文件的路径,如果存在,则跳过要执行的命令。

    显示的剧本检查文件是否hello.txt存在于目标主机的主目录中。如果该文件不存在,则执行指定的shell命令。如果该文件存在,则shell命令将中止。

    -name:Createafileinthehomedirectoryifitdoesn'texist

    -name:Createafileinthehomedirectory

    shell:echo"Heyguys!">$HOME/hello.txt

    creates:"$HOME/hello.txt"

    由于该文件在远程目标上不存在,因此shell命令已成功执行,如您从playbook执行中所见。

    下面的命令确认hello.txt文件是在远程目标的主目录中创建的。

    sshroot@173.82.120.115"ls-l~"

    如何使用Ansible,ansibleshell模块

    参数指定文件名,removes如果文件存在,则执行命令。在前面的示例中,该hello.txt文件是在远程目标的主目录中创建的。

    在此剧本中,removes参数检查此文件是否存在于远程目标上。由于您已经创建了它,剧本会继续执行删除文件的shell命令。

    -name:Removeafileinthehomedirectoryonlyifitexists

    -name:Removeafileinthehomedirectory

    removes:"$HOME/hello.txt"

    剧本执行确认文件已被删除。

    要在特定目录中运行shell命令,请使用chdir参数。下面的剧本将Apache二进制文件下载到/usr/local/src路径中。

    -name:DownloadApachesourcefileto/usr/local/srcdirectory

    -name:DownloadApachetarballfile

    shell:wgethttps://dlcdn.apache.org/httpd/httpd-2.4.52.tar.gz

    将Ansibleshell模块与环境变量一起使用

    shell模块还使您能够设置新的环境变量。使用environment参数可以做到这一点。考虑下面的剧本。

    -name:Environmentvariableexample

    -name:AnsibleShellmodulesetanenvironmentvariable

    msg:"{{command_result.stdout_lines}}"

    该剧本将NEW_VAR环境变量设置为john_doe。

    注意:环境变量仅为该特定任务设置。在后续任务中,NEW_VAR变量将不可用。

    使用AnsibleShell模块运行多个命令

    到目前为止,您已经看到shell模块在托管主机上运行单个命令。您还可以指定一组按时间顺序执行的命令。

    要实现这一点,请使用竖线开始shell命令,然后是要执行的任务列表。在本例中,date、uptime、和echo命令的输出分别保存到date.txt、uptime.txt和hello.txt文件中,然后保存在/tmp目录中。

    -name:Shellmoduleexample

    -name:Runmultiplecommands

    uptime>/tmp/uptime.txt

    echo"HelloWorld">/tmp/hello.txt

    剧本从第一个任务到最后一个任务按顺序运行任务。

    如前所述,shell模块也接受管道和重定向。事实上,之前的剧本利用重定向符号(?>)将列出的命令的输出保存到单独的文件中。

    假设您要列出在/tmp目录中创建的所有文本文件,并将结果保存到同一目录中另一个名为dirlist.txt的文件中。

    ls-l/tmp|grep.txt>/tmp/dirlist.txt

    命令的第一部分列出了/tmp目录中的所有文件。然后将结果通过管道传输到grep命令,该命令过滤输出以仅包含文本文件。然后使用“大于”重定向符号将最终输出保存到dirlist.txt文件。

    现在让我们更进一步,将结果打印到标准输出。为此,需要第二项任务。目标是将dirlist.txt文件的内容显示到标准输出。列出文件内容的shell命令是:

    命令的输出随后被注册在一个名为displayfile的变量中,并且使用调试模块将消息显示到标准输出。这是整个剧本的样子。

    -name:Shellmoduleexample

    -name:Listtextfilesintmpdirectoryandsaveresultinoutputfile

    shell:"ls-l/tmp|grep.txt>/tmp/dirlist.txt

    -name:Displaythecontentsoftheoutputfile

    shell:cat/tmp/dirlist.txt

    msg:"{{displayfile.stdout_lines}}"

    执行playbook时,/tmp目录中的所有文本文件(包括dirlist.txt文件)都会打印到标准输出:

    由于它在远程目标的shell上运行命令,因此shell模块容易受到shell命令注入。Shell注入是一种攻击媒介,攻击者在其中在主机上运行任意命令以破坏底层基础设施。

    使用Shell模块变量时,Ansible建议使用quote过滤器来阻止shell注入威胁。

    -name:Ansiblequotefilterdemo

    msg:"Runningplaybookasuser{{username|quote}}

    该username变量在最后由msg使用过滤器的参数引用,quote以防止在注入用户名变量时执行任意命令字符串。

    Ansibleshell模块是一个有用的模块,可以帮助您在托管主机上快速执行简单任务。shell模块的完美替代品是commandmodule。它提供了一种更可靠、更安全的任务执行方式,因为命令不会在远程目标的shell上处理。如果您坚持使用shell模块,请不要忘记quote在playbook中使用模板化变量时包含过滤器以防止shell注入攻击。

    标签:
    哪家韩国VPS好(我们推荐CN2线路的Kdatacenter)
    « 上一篇
    返回列表
    下一篇 »

    如本文对您有帮助,就请抽根烟吧!