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?

John Doe
quelle
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.

Pedro Romano
quelle
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
Arvik
quelle
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",
AKS
quelle
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

Arbab Nazar
quelle
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

Kalu Wang
quelle
0

Hier ist ein Arbeiter wie dieser. \Ö/

- name: "Exec items"
  shell: "{{ item }}"
  with_items:
    - echo "hello"
    - echo "hello2"
user3740244
quelle