ansible:如何传递多个命令


76

我尝试了这个:

- 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

说行情存在问题,那是行不通的。

任何人?


3
嗯,尝试使用该shell模块。如果您阅读命令模块上的文档,您将了解为什么它不起作用。(不是完整的答案,因为我还没有测试过)
tedder42

很抱歉,但是我之前确实阅读过shell和命令文档,但我仍然不知道为什么它不起作用。
约翰·多伊

我使用带分号的shell模块作为分隔符,该分隔符有效:shell:echo“ a”; 回声“ b”
彼得·斯莫尔伍德

Answers:


99

如果YAML中的值以大括号({)开头,则YAML解析器将假定它为字典。因此,对于这种情况,在值中包含(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的替代建议。


在某些情况下(例如,当它们包含空格时),您确实需要引用变量。
Pedro Romano 2014年

5
您需要在整个命令周围加上双引号。问题在于值的第一个字符是“ {”,在YAML中具有含义。因此,它是-命令:“ {{item}} chdir = / src / package /”
Ramon de la Fuente 2014年

如果您的一项中有变量怎么办?即-cp {{base_dir}}
4m1r

任何字符串(包括带有变量的字符串)的安全选项是简单地引用整个字符串:"cp {{base_dir}}"
Pedro Romano

80

要使用ansible运行多个shell命令,可以将shell模块与多行字符串一起使用(请注意后面的管道shell:),如以下示例所示:

  - name: Build nginx 
    shell: |
      cd nginx-1.11.13
      sudo ./configure
      sudo make
      sudo make install

谢谢。有没有办法告诉它忽略故障并继续执行列表中的后续命令?
sogwiz

5

我遇到了同样的问题。就我而言,我的部分变量在字典中,即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 }}"

角色/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”模块,并在role / git / defaults / main.yml中创建了一个变量

因此,现在role / 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"

任务角色/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

壳牌为我工作。

简而言之,Shell与运行Shell脚本相同。

笔记:

  1. 确保使用| 运行多个cmds时。
  2. 如果最后一个cmd成功,则Shell不会返回错误(就像普通的Shell一样)
  3. 如果要在发生错误时停止ansible,请使用出口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

此示例显示stopinng 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


0

这是这样的工人。\ o /

- name: "Exec items"
  shell: "{{ item }}"
  with_items:
    - echo "hello"
    - echo "hello2"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.