[英]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 之外的任何主机运行此脚本,并注意脚本的stdout
和stderr
。
#!/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.