【问题标题】:ansible : how to pass multiple commandsansible:如何传递多个命令
【发布时间】: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://stackoverflow.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”

标签: module command ansible


【解决方案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 脚本是一样的。

      注意事项:

      1. 确保在运行多个 cmd 时使用 |
      2. 如果最后一个 cmd 成功,Shell 不会返回错误(就像普通的 shell)
      3. 如果您想在发生错误时停止 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"
        

        【讨论】:

          猜你喜欢
          • 2016-08-28
          • 1970-01-01
          • 2012-06-02
          • 2020-11-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-20
          • 2017-11-30
          相关资源
          最近更新 更多