ansible: wie man mehrere Befehle übergibt


75

Ich habe es versucht:

- command: ./configure chdir=/src/package/
- command: /usr/bin/make chdir=/src/package/
- command: /usr/bin/make install chdir=/src/package/

was funktioniert, aber ich denke, es gibt etwas mehr .. ordentlich.

Also habe ich das versucht:

von: /programming/24043561/multiple-commands-in-the-same-line-for-bruker-topspin, die mir "keine solche Datei oder kein solches Verzeichnis" zurückgeben

- command: ./configure;/usr/bin/make;/usr/bin/make install chdir=/src/package/

Ich habe es auch versucht: https://u.osu.edu/hasnan.1/2013/12/16/ansible-run-multiple-commands-using-command-module-and-with-items/

aber ich konnte nicht die richtige Syntax finden, um zu setzen:

- command: "{{ item }}" chdir=/src/package/
  with_items:
      ./configure
      /usr/bin/make
      /usr/bin/make install

Das funktioniert nicht, da es ein Zitatproblem gibt.

Jemand?


3
Versuchen Sie es mit dem shellModul. Wenn Sie die Dokumente auf dem Befehlsmodul lesen, werden Sie sehen, warum es nicht funktioniert. (keine vollständige Antwort, da ich sie nicht getestet habe)
— tedder42

Tut mir leid, aber ich habe die Shell- und Befehlsdokumente schon einmal gelesen und weiß immer noch nicht, warum es nicht funktioniert.
— John Doe

Ich habe das Shell-Modul mit Semikolons als Trennzeichen verwendet, was funktioniert hat: shell: echo "a"; Echo "b"
— Peter Smallwood

Antworten:


98

Wenn ein Wert in YAML mit einer geschweiften Klammer ( {) beginnt , geht der YAML-Parser davon aus, dass es sich um ein Wörterbuch handelt . In solchen Fällen, in denen der Wert eine (Jinja2) -Variable enthält, muss eine der beiden folgenden Strategien angewendet werden, um eine Verwechslung des YAML-Parsers zu vermeiden:

Zitiere den ganzen Befehl:

- command: "{{ item }} chdir=/src/package/"
  with_items:
  - ./configure
  - /usr/bin/make
  - /usr/bin/make install    

oder ändern Sie die Reihenfolge der Argumente:

- command: chdir=/src/package/ {{ item }}
  with_items:
  - ./configure
  - /usr/bin/make
  - /usr/bin/make install

Vielen Dank für den alternativen Vorschlag von @RamondelaFuente.


In einigen Situationen müssen Sie die Variablen in Anführungszeichen setzen, z. B. wenn sie Leerzeichen enthalten.
— Pedro Romano

5
Sie benötigen doppelte Anführungszeichen um den gesamten Befehl. Das Problem liegt darin, dass das erste Zeichen des Werts ein "{" ist, das in YAML eine Bedeutung hat. Also ist es - Befehl: "{{item}} chdir = / src / package /"
— Ramon de la Fuente

Was ist, wenn Sie eine Variable in einem Ihrer Artikel haben? dh - cp {{base_dir}}
— 4m1r

Die sichere Option für jede Zeichenfolge (einschließlich solcher mit Variablen) besteht darin, einfach die gesamte Zeichenfolge in Anführungszeichen zu setzen : "cp {{base_dir}}".
— Pedro Romano

77

Um mehrere Shell-Befehle mit ansible auszuführen, können Sie das Shell- Modul mit einer mehrzeiligen Zeichenfolge verwenden (beachten Sie die Pipe danach shell:), wie in diesem Beispiel gezeigt:

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

Vielen Dank. Gibt es eine Möglichkeit, Fehler anzuweisen und mit den nachfolgenden Befehlen in der Liste fortzufahren?
— Sogwiz

5

Ich stand vor dem gleichen Problem. In meinem Fall befand sich ein Teil meiner Variablen in einem Wörterbuch, dh mit der Variablen with_dict (Schleife), und ich musste 3 Befehle für jeden item.key ausführen. Diese Lösung ist relevanter, wenn Sie das Wörterbuch with_dict verwenden müssen, um mehrere Befehle auszuführen ( ohne dass with_items erforderlich ist ).

Die Verwendung von with_dict und with_items in einer Aufgabe hat nicht geholfen, da die Variablen nicht aufgelöst wurden.

Meine Aufgabe war wie:

- 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 }}"

Rollen / git / defaults / main.yml war:

---
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

Das Obige führte zu einem Fehler ähnlich dem folgenden für jedes {{item}} (für 3 Befehle wie oben erwähnt). Wie Sie sehen, werden die Werte von tools_dir nicht ausgefüllt (tools_dir ist eine Variable, die in den Standardwerten / main.yml einer allgemeinen Rolle definiert ist, und der Wert item.value.git_tar_dir wurde nicht ausgefüllt / aufgelöst).

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

Die Lösung war einfach. Anstatt das "COMMAND" -Modul in Ansible zu verwenden, habe ich das "Shell" -Modul verwendet und eine Variable in den Rollen / git / defaults / main.yml erstellt

Nun sieht die Rolle / git / defaults / main.yml folgendermaßen aus:

---
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"

und die Aufgabenrollen / git / task / main.yml sehen wie folgt aus:

- name: Make install from git source
  shell: "{{ git_pre_requisites_install_cmds }}"
  become_user: "{{ build_user }}"
  with_dict: "{{ git_versions }}"
  tags:
    - koba

Dieses Mal wurden die Werte erfolgreich ersetzt, da das Modul "SHELL" war und die Ansible-Ausgabe die korrekten Werte wiedergab. Dies erforderte keine with_items: Schleife.

"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",

4

Sie können auch so vorgehen:

- command: "{{ item }}"
  args:
    chdir: "/src/package/"
  with_items:
    - "./configure"
    - "/usr/bin/make"
    - "/usr/bin/make install"

Hoffe das könnte anderen helfen


3

Shell arbeitet für mich.

Einfach gesagt, Shell ist dasselbe, wie Sie ein Shell-Skript ausführen.

Anmerkungen:

  1. Stellen Sie sicher, dass Sie | verwenden beim Ausführen mehrerer cmds.
  2. Die Shell gibt keine Fehler zurück, wenn das letzte cmd erfolgreich ist (genau wie bei einer normalen Shell).
  3. Steuern Sie es mit Exit 0/1, wenn Sie ansible stoppen möchten, wenn ein Fehler auftritt.

Das folgende Beispiel zeigt einen Fehler in der Shell, der jedoch am Ende der Ausführung erfolgreich ist.

- name: test shell with an error
become: no
shell: |
  rm -f /test1  # This should be an error.
  echo "test2"
  echo "test1"
  echo "test3" # success

Dieses Beispiel zeigt das Stoppen der Shell mit dem Fehler von Exit 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

Referenz: https://docs.ansible.com/ansible/latest/modules/shell_module.html


0

Hier ist ein Arbeiter wie dieser. \Ö/

- name: "Exec items"
  shell: "{{ item }}"
  with_items:
    - echo "hello"
    - echo "hello2"
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.