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

我正在计划使用安塞尔剧本在远程服务器上执行一个 shell 脚本。

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

当我运行剧本时,转移成功发生,但脚本没有执行。

274040 次浏览

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

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

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

它应该做到这一点。

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

根据 游戏手册入门user参数在 Ansible 被重新命名为 remote_user1.4,所以你也应该改变它

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

你可以使用 译自: 美国《科学》杂志网站(http://docs.ansible.com/anable/update/Collection/anable/builtin/script _ module.html # example)模块

例子

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


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

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

 - 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

因为有人想要一个特别的命令

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

或使用相对路径

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

与所有其他的回答和评论相反,使用 script模块有一些缺点。特别是在远程(而非本地主机)主机上运行时。下面是来自 官方可检验的文件的一个片段:

通常情况下,编写 Anable 模块比推送更可取 把你的脚本转换成一个可视化模块以获得额外加分

Ssh 连接插件将强制通过 -tt 进行伪 tty 分配 当脚本被执行的时候 所有的 stderr 都被发送到 stdout。 < strong > 如果您依赖于分离的 stdout 和 stderr 结果键,请切换到任务的 copy + 命令集 而不是使用 script.

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

Windows 目标也支持此模块。

例如,对任何主机 除了本地主机使用 script模块运行此脚本,并注意脚本的 stdoutstderr

#!/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"
]
}
}

文档不鼓励用户使用脚本模块; 请考虑将您的脚本转换为可变模块; 这里是我的一个 简单的邮件,它解释了如何将您的脚本转换为可变模块。

您可以在 anable 执行本地脚本,而不必将文件传输到远程服务器,这种方法是:

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

由于没有定义关于“脚本” 的任何内容,意味着复杂性、内容、运行时、执行期函式库、大小、要执行的任务等等都是未知的,所以可以像“ 如何复制命令提示符中提供的内容,并在文件中使用特殊字符”中那样使用 不推荐的方法

---
- 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 命令(annot. : ... 只是内联代码) ,并导致输出为

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

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


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

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

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