[英]How to execute a shell script on a remote server using Ansible?
I am planning to execute a shell script on a remote server using Ansible playbook.我计划使用 Ansible 剧本在远程服务器上执行 shell 脚本。
blank test.sh file:空白 test.sh 文件:
touch test.sh
Playbook:剧本:
---
- 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
When I run the playbook, the transfer successfully occurs but the script is not executed.当我运行剧本时,传输成功,但脚本没有执行。
local_action
runs the command on the local server, not on the servers you specify in hosts
parameter. local_action
在本地服务器上运行命令,而不是在您在hosts
参数中指定的服务器上运行。
Change your "Execute the script" task to将“执行脚本”任务更改为
- name: Execute the script
command: sh /home/test_user/test.sh
and it should do it.它应该这样做。
You don't need to repeat sudo in the command line because you have defined it already in the playbook.您不需要在命令行中重复 sudo ,因为您已经在剧本中定义了它。
According to Ansible Intro to Playbooks user
parameter was renamed to remote_user
in Ansible 1.4 so you should change it, too根据Ansible Intro to Playbooks user
参数在 Ansible 1.4 中重命名为remote_user
所以你也应该改变它
remote_user: test_user
So, the playbook will become:所以,剧本将变成:
---
- 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
It's better to use script
module for that:最好为此使用script
模块:
http://docs.ansible.com/script_module.html http://docs.ansible.com/script_module.html
For someone wants an ad-hoc command对于想要临时命令的人
ansible group_or_hostname -m script -a "/home/user/userScript.sh"
or use relative path或使用相对路径
ansible group_or_hostname -m script -a "userScript.sh"
Contrary to all the other answers and comments, there are some downsides to using the script
module.与所有其他答案和评论相反,使用script
模块有一些缺点。 Especially when you are running it on a remote(not localhost) host.特别是当您在远程(不是本地主机)主机上运行它时。 Here is a snippet from the official ansible documentation :这是官方 ansible 文档的片段:
It is usually preferable to write Ansible modules rather than pushing scripts.通常最好编写 Ansible 模块而不是推送脚本。 Convert your script to an Ansible module for bonus points!将您的脚本转换为 Ansible 模块以获得奖励积分!
The ssh connection plugin will force pseudo-tty allocation via -tt when scripts are executed. ssh 连接插件将在执行脚本时通过 -tt 强制分配伪 tty。 Pseudo-ttys do not have a stderr channel and all stderr is sent to stdout.伪 tty 没有标准错误通道,所有标准错误都发送到标准输出。 If you depend on separated stdout and stderr result keys, please switch to a copy+command set of tasks instead of using script.如果您依赖分离的 stdout 和 stderr 结果键,请切换到复制+命令任务集,而不是使用脚本。
If the path to the local script contains spaces, it needs to be quoted.如果本地脚本的路径包含空格,则需要加引号。
This module is also supported for Windows targets. Windows 目标也支持此模块。
For example, run this script using script
module for any host other than localhost and notice the stdout
and stderr
of the script.例如,使用script
模块为除localhost 之外的任何主机运行此脚本,并注意脚本的stdout
和stderr
。
#!/bin/bash
echo "Hello from the script"
nonoexistingcommand
echo "hello again"
You will get something like the below;你会得到类似下面的东西; notice the stdout
has all the stderr
merged.(ideally line 6: nonoexistingcommand: command not found
should be in stderr
) So, if you are searching for some substring in stdout in the script output.请注意stdout
已合并所有stderr
。(理想情况下, line 6: nonoexistingcommand: command not found
应该在stderr
中)因此,如果您在脚本 output 的标准输出中搜索一些 substring。 you may get incorrect results.:您可能会得到不正确的结果。:
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"
]
}
}
The documentation is not encouraging users to use the script module;该文档不鼓励用户使用脚本模块; consider converting your script into an ansible module;考虑将您的脚本转换为 ansible 模块; here is a simple post by me that explains how to convert your script into an ansible module.这是我的一个 简单帖子,解释了如何将您的脚本转换为 ansible 模块。
You can execute local scripts at ansible without having to transfer the file to the remote server, this way:您可以在 ansible 执行本地脚本,而无需将文件传输到远程服务器,这样:
ansible my_remote_server -m shell -a "`cat /localpath/to/script.sh`"
Since nothing is defined about "the script" , means complexity, content, runtime, runtime environment, size, tasks to perform, etc. are unknown, it might be possible to use an unrecommended approach like in " How to copy content provided in command prompt with special chars in a file using Ansible? "由于没有关于“脚本”的任何定义,意味着复杂性、内容、运行时、运行时环境、大小、要执行的任务等都是未知的,因此可以使用不推荐的方法,例如“如何复制命令中提供的内容”使用 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 }}"
which is a multi-line shell command only and resulting into an output of这是一个多行 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
One could just add more lines, complexity, necessary output, etc.可以添加更多行、复杂性、必要的 output 等。
Because of script
module – Runs a local script on a remote node after transferring it - Notes由于script
模块 - 传输后在远程节点上运行本地脚本 - 注释
It is usually preferable to write Ansible modules rather than pushing scripts.通常最好编写 Ansible 模块而不是推送脚本。
I also recommend to get familar with writing an own module and as already mentioned in the answer of P....我还建议熟悉编写自己的模块,正如P.... 的答案中已经提到的那样
You can use template module to copy if script exists on local machine to remote machine and execute it.您可以使用模板模块将本地机器上是否存在脚本复制到远程机器并执行它。
- 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.