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传递列表作为变量

Ansible 学习总结(10)—— 自动化部署工具如何选?Saltstack Or Ansible

Ansible 学习总结(10)—— 自动化部署工具如何选?Saltstack Or Ansible

ansible debug模块学习笔记

ansible debug模块学习笔记

ansible-hoc命令行