Ist es möglich, eine XML-Datei über ein Shell-Skript zu ändern?

11

So sieht meine docker-compose.yml aus.

nginx:
  container_name: 'nginx'
  image: 'nginx:1.11'
  restart: 'always'
  ports:
    - '80:80'
    - '443:443'
  volumes:
    - '/opt/nginx/conf.d:/etc/nginx/conf.d:ro'
  links:
    - 'anything'

Jetzt muss ich einige Inhalte über ein Shell-Skript hinzufügen (auf einem Ubuntu-Server). Ich bin mir nicht ganz sicher, ob es überhaupt möglich ist:

  1. Fügen Sie ein neues Element hinzu nginx/links, falls es nicht vorhanden ist
  2. Anfügen newthingBlock , wenn kein newthing-Block vorhanden ist

Der neue Inhalt sollte folgendermaßen aussehen:

nginx:
  container_name: 'nginx'
  image: 'nginx:1.11'
  restart: 'always'
  ports:
    - '80:80'
    - '443:443'
  volumes:
    - '/opt/nginx/conf.d:/etc/nginx/conf.d:ro'
    - '/etc/letsencrypt:/etc/letsencrypt'
  links:
    - 'anything'
    - 'newthing'

newthing:
  container_name: foo
  image: 'newthing:1.2.3'
  restart: always
  hostname: 'example.com'
user3142695
quelle
1
Shell bietet Ihnen eine sehr leistungsfähige Skriptsprache. Sie können ganz einfach ein Skript schreiben sed, awkund die regular expressionsDateien zu aktualisieren.
Fossil
Könnten Sie bitte ein kleines Beispiel geben?
user3142695
2
Während dies mit Shell technisch möglich ist, sollten Sie besser eine Sprache verwenden, die über eine tatsächliche Yaml-Bibliothek verfügt.
Jordanm
Ich würde Ihnen raten, die ruamel.yamlBibliothek für Python zu überprüfen .
Phk
Ich denke, es ist erwähnenswert, dass Links eine Legacy-Funktion sind, die in Zukunft aus Docker entfernt wird: docs.docker.com/compose/compose-file/#links
Mikael Kjær

Antworten:

6

Es gibt eine Reihe von Yaml-Bibliotheken für Perl, Python usw., wenn es in Ordnung ist, dies nicht direkt über ein Shell-Skript zu tun, sondern eine andere Sprache zu verwenden.

Eine andere Möglichkeit besteht darin, einen Befehlszeilen- Yaml-Prozessor zu installieren und ihn von Ihrem Shell-Skript aus aufzurufen.

dirkt
quelle
8

Ich habe https://github.com/kislyuk/yq geschrieben , einen Wrapper um https://stedolan.github.io/jq/ , um diesen Anwendungsfall zu behandeln.

Weber
quelle
Kann es ein Update durchführen?
Weynhamz
1
Ja : yq -y '.newthing=...' input.yml > output.yml. (Wenn Sie nach einem Update fragen sed -i, kann yq es noch nicht alleine machen, aber Sie können verwenden sponge: yq -y .newthing=... file.yml | sponge file.yml.)
Weber
1
@ Weaver du bist mein neuer Held
Voutasaurus
7

Ich habe yaml_cli ( https://github.com/Gallore/yaml_cli ) geschrieben, um genau das zu tun, was Sie brauchen. Es basiert auf Python. Dies wäre die Syntax für Ihr Beispiel:

yaml_cli \
  -f docker-compose.yml \                # read from and save to file
  --list-append \                        # flag to append to lists instead of replacing existing values
  -s nginx:links newthing \              # add a value of type string; here you need --list-append
  -s newthing:container_name foo \       # key 'newthing' is created automatically
  -s newthing:image 'newthing:1.2.3' \   #
  -s newthing:restart always \           #
  -s newthing:hostname 'example.com'     #

Feedback zu yaml_cli ist willkommen.

Andy Werner
quelle
1

Da der Grund dafür darin besteht, eine Docker-Compose-Datei zu ändern, besteht eine andere Alternative darin, eine JSON-Datei zu verwenden. Docker-Compose unterstützt jetzt JSON-Dateien . Die Unterstützung für die Befehlszeilenmanipulation von JSONs ist bereits sehr gut (Beispiel: jq )

Vivek Kodira
quelle