ansible:如何传递多个命令
Posted
技术标签:
【中文标题】ansible:如何传递多个命令【英文标题】:ansible : how to pass multiple commands 【发布时间】:2014-09-11 03:50:40 【问题描述】:我试过这个:
- command: ./configure chdir=/src/package/
- command: /usr/bin/make chdir=/src/package/
- command: /usr/bin/make install chdir=/src/package/
这可行,但我想还有更多……整洁。
所以我尝试了这个:
来自:https://***.com/questions/24043561/multiple-commands-in-the-same-line-for-bruker-topspin 这给了我“没有这样的文件或目录”
- command: ./configure;/usr/bin/make;/usr/bin/make install chdir=/src/package/
我也试过这个:https://u.osu.edu/hasnan.1/2013/12/16/ansible-run-multiple-commands-using-command-module-and-with-items/
但我找不到正确的语法:
- command: " item " chdir=/src/package/
with_items:
./configure
/usr/bin/make
/usr/bin/make install
这不起作用,说有报价问题。
有人吗?
【问题讨论】:
很抱歉,我之前确实阅读过 shell 和命令文档,但我仍然不知道为什么它不起作用。 我使用了带有分号的shell模块作为分隔符:shell: echo "a";回声“b” 【参考方案1】:如果 YAML 中的值以大括号 () 开头,则 YAML 解析器假定它是 a dictionary。因此,对于这种值中有 (Jinja2) 变量的情况,需要采用以下两种策略之一来避免混淆 YAML 解析器:
引用整个命令:
- command: " item chdir=/src/package/"
with_items:
- ./configure
- /usr/bin/make
- /usr/bin/make install
或更改参数的顺序:
- command: chdir=/src/package/ item
with_items:
- ./configure
- /usr/bin/make
- /usr/bin/make install
感谢@RamondelaFuente 的替代建议。
【讨论】:
在某些情况下确实需要引用变量,例如当它们包含空格时。 整个命令需要双引号。问题在于值的第一个字符是“”,它在 YAML 中有意义。所以它是 - 命令:“ item chdir=/src/package/” 如果您的某件商品中有变量怎么办?即 - cp base_dir 任何字符串(包括带有变量的字符串)的安全选项是简单地引用整个字符串:"cp base_dir"
。【参考方案2】:
我遇到了同样的问题。就我而言,我的部分变量在字典中,即 with_dict 变量(循环),我必须在每个 item.key 上运行 3 个命令。当您必须使用 with_dict 字典来运行多个命令时,此解决方案更为相关(不需要 with_items)
在一项任务中使用 with_dict 和 with_items 没有帮助,因为它没有解析变量。
我的任务是这样的:
- name: Make install git source
command: " item "
with_items:
- cd tools_dir / item.value.artifact_dir
- make prefix= tools_dir / item.value.artifact_dir all
- make prefix= tools_dir / item.value.artifact_dir install
with_dict: " git_versions "
roles/git/defaults/main.yml 是:
---
tool: git
default_git: git_2_6_3
git_versions:
git_2_6_3:
git_tar_name: git-2.6.3.tar.gz
git_tar_dir: git-2.6.3
git_tar_url: https://www.kernel.org/pub/software/scm/git/git-2.6.3.tar.gz
对于每个 item (对于上面提到的 3 个命令),上述导致类似于以下的错误。如您所见,tools_dir 的值未填充(tools_dir 是一个在通用角色的 defaults/main.yml 中定义的变量,并且 item.value.git_tar_dir 的值未填充/解析)。
failed: [server01.poc.jenkins] => (item=cd # tools_dir #/# item.value.git_tar_dir #) => "cmd": "cd '#' tools_dir '#/#' item.value.git_tar_dir '#'", "failed": true, "item": "cd # tools_dir #/# item.value.git_tar_dir #", "rc": 2
msg: [Errno 2] No such file or directory
解决方案很简单。我没有在 Ansible 中使用“COMMAND”模块,而是使用“Shell”模块并在角色/git/defaults/main.yml 中创建了一个变量
所以,现在角色/git/defaults/main.yml 看起来像:
---
tool: git
default_git: git_2_6_3
git_versions:
git_2_6_3:
git_tar_name: git-2.6.3.tar.gz
git_tar_dir: git-2.6.3
git_tar_url: https://www.kernel.org/pub/software/scm/git/git-2.6.3.tar.gz
#git_pre_requisites_install_cmds: "cd tools_dir / item.value.git_tar_dir && make prefix= tools_dir / item.value.git_tar_dir all && make prefix= tools_dir / item.value.git_tar_dir install"
#or use this if you want git installation to work in ~/tools/git-x.x.x
git_pre_requisites_install_cmds: "cd tools_dir / item.value.git_tar_dir && make prefix=`pwd` all && make prefix=`pwd` install"
#or use this if you want git installation to use the default prefix during make
#git_pre_requisites_install_cmds: "cd tools_dir / item.value.git_tar_dir && make all && make install"
任务 roles/git/tasks/main.yml 看起来像:
- name: Make install from git source
shell: " git_pre_requisites_install_cmds "
become_user: " build_user "
with_dict: " git_versions "
tags:
- koba
这一次,值被成功替换,因为模块是“SHELL”,并且 ansible 输出回显了正确的值。 这不需要 with_items: 循环。
"cmd": "cd ~/tools/git-2.6.3 && make prefix=/home/giga/tools/git-2.6.3 all && make prefix=/home/giga/tools/git-2.6.3 install",
【讨论】:
【参考方案3】:你也可以这样做:
- command: " item "
args:
chdir: "/src/package/"
with_items:
- "./configure"
- "/usr/bin/make"
- "/usr/bin/make install"
希望对其他人有所帮助
【讨论】:
【参考方案4】:要使用 ansible 运行多个 shell 命令,您可以使用带有多行字符串的 shell 模块(注意 shell:
之后的 管道),如下所示示例:
- name: Build nginx
shell: |
cd nginx-1.11.13
sudo ./configure
sudo make
sudo make install
【讨论】:
谢谢。有没有办法告诉它忽略失败并继续执行列表中的后续命令?【参考方案5】:Shell 适合我。
简单地说,Shell 和你运行一个 shell 脚本是一样的。
注意事项:
-
确保在运行多个 cmd 时使用 |。
如果最后一个 cmd 成功,Shell 不会返回错误(就像普通的 shell)
如果您想在发生错误时停止 ansible,请使用 exit 0/1 控制它。
以下示例显示了shell中的错误,但在执行结束时成功。
- name: test shell with an error
become: no
shell: |
rm -f /test1 # This should be an error.
echo "test2"
echo "test1"
echo "test3" # success
此示例显示停止 shell 并出现退出 1 错误。
- name: test shell with exit 1
become: no
shell: |
rm -f /test1 # This should be an error.
echo "test2"
exit 1 # this stops ansible due to returning an error
echo "test1"
echo "test3" # success
参考: https://docs.ansible.com/ansible/latest/modules/shell_module.html
【讨论】:
【参考方案6】:这里有这样的工人。 \o/
- name: "Exec items"
shell: " item "
with_items:
- echo "hello"
- echo "hello2"
【讨论】:
以上是关于ansible:如何传递多个命令的主要内容,如果未能解决你的问题,请参考以下文章
Ansible 学习总结(10)—— 自动化部署工具如何选?Saltstack Or Ansible