繁体   English   中英

如何使用 Ansible 在远程服务器上执行 shell 脚本?

[英]How to execute a shell script on a remote server using Ansible?

我计划使用 Ansible 剧本在远程服务器上执行 shell 脚本。

空白 test.sh 文件:

touch test.sh

剧本:

---
- name: Transfer and execute a script.
  hosts: server
  user: test_user
  sudo: yes
  tasks:
     - name: Transfer the script
       copy: src=test.sh dest=/home/test_user mode=0777

     - name: Execute the script
       local_action: command sudo sh /home/test_user/test.sh

当我运行剧本时,传输成功,但脚本没有执行。

您可以使用脚本模块

例子

- name: Transfer and execute a script.
  hosts: all
  tasks:

     - name: Copy and Execute the script 
       script: /home/user/userScript.sh

local_action在本地服务器上运行命令,而不是在您在hosts参数中指定的服务器上运行。

将“执行脚本”任务更改为

- name: Execute the script
  command: sh /home/test_user/test.sh

它应该这样做。

您不需要在命令行中重复 sudo ,因为您已经在剧本中定义了它。

根据Ansible Intro to Playbooks user参数在 Ansible 1.4 中重命名为remote_user所以你也应该改变它

remote_user: test_user

所以,剧本将变成:

---
- name: Transfer and execute a script.
  hosts: server
  remote_user: test_user
  sudo: yes
  tasks:
     - name: Transfer the script
       copy: src=test.sh dest=/home/test_user mode=0777

     - name: Execute the script
       command: sh /home/test_user/test.sh

最好为此使用script模块:
http://docs.ansible.com/script_module.html

对于想要临时命令的人

ansible group_or_hostname -m script -a "/home/user/userScript.sh"

或使用相对路径

ansible group_or_hostname -m script -a "userScript.sh"

与所有其他答案和评论相反,使用script模块有一些缺点。 特别是当您在远程(不是本地主机)主机上运行它时。 这是官方 ansible 文档的片段:

通常最好编写 Ansible 模块而不是推送脚本。 将您的脚本转换为 Ansible 模块以获得奖励积分!

ssh 连接插件将在执行脚本时通过 -tt 强制分配伪 tty。 伪 tty 没有标准错误通道,所有标准错误都发送到标准输出。 如果您依赖分离的 stdout 和 stderr 结果键,请切换到复制+命令任务集,而不是使用脚本。

如果本地脚本的路径包含空格,则需要加引号。

Windows 目标也支持此模块。

例如,使用script模块为localhost 之外的任何主机运行此脚本,并注意脚本的stdoutstderr

#!/bin/bash


echo "Hello from the script"

nonoexistingcommand

echo "hello again"

你会得到类似下面的东西; 请注意stdout已合并所有stderr 。(理想情况下, line 6: nonoexistingcommand: command not found应该在stderr中)因此,如果您在脚本 output 的标准输出中搜索一些 substring。 您可能会得到不正确的结果。:

 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 模块; 这是我的一个 简单帖子,解释了如何将您的脚本转换为 ansible 模块。

您可以在 ansible 执行本地脚本,而无需将文件传输到远程服务器,这样:

ansible my_remote_server -m shell -a "`cat /localpath/to/script.sh`"

由于没有关于“脚本”的任何定义,意味着复杂性、内容、运行时、运行时环境、大小、要执行的任务等都是未知的,因此可以使用不推荐的方法,例如“如何复制命令中提供的内容使用 Ansible 在文件中使用特殊字符提示?

---
- hosts: test
  become: false
  gather_facts: false

  tasks:

  - name: Exec sh script on Remote Node
    shell:
      cmd: |
        date
        ps -ef | grep ssh
        echo "That's all folks"
    register: result

  - name: Show result
    debug:
      msg: "{{ result.stdout }}"

这是一个多行 shell 命令,并导致 output

TASK [Show result] ****************************************************
ok: [test.example.com] =>
  msg: |-
    Sat Sep 3 21:00:00 CEST 2022
    root        709      1  0 Aug11 ?        00:00:00 /usr/sbin/sshd -D
    root     123456    709 14 21:00 ?        00:00:00 sshd: user [priv]
    user     123456 123456  1 21:00 ?        00:00:00 sshd: user@pts/0
    root     123456 123456  0 21:00 pts/0    00:00:00 grep ssh
    That's all folks

可以添加更多行、复杂性、必要的 output 等。


由于script模块 - 传输后在远程节点上运行本地脚本 - 注释

通常最好编写 Ansible 模块而不是推送脚本。

我还建议熟悉编写自己的模块,正如P.... 的答案中已经提到的那样

您可以使用模板模块将本地机器上是否存在脚本复制到远程机器并执行它。

 - name: Copy script from local to remote machine
   hosts: remote_machine
   tasks:
    - name: Copy  script to remote_machine
      template: src=script.sh.2 dest=<remote_machine path>/script.sh mode=755
    - name: Execute script on remote_machine
      script: sh <remote_machine path>/script.sh

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM