web-dev-qa-db-fra.com

Comment échapper aux guillemets simples et doubles en YAML dans la même chaîne

Je dois échapper correctement aux guillemets simples et doubles d'un livre de jeu ansible afin de définir la variable d'environnement. Rien de cela ne fonctionne:

  - name: Set environment variable
    command: >
      export EXTRA_CONFIG=“'”{"client": {"subscriptions": ["DIND-Worker"], "cluster": "internal"}}“'”

  - name: Set environment variable
    command: >
      export EXTRA_CONFIG=''{"client": {"subscriptions": ["DIND-Worker"], "cluster": "internal"}}''

  - name: Set environment variable
    command: >
      export EXTRA_CONFIG=''{\"client\": {\"subscriptions\": [\"DIND-Worker\"], \"cluster\": \"internal\"}}''

Regardé ceci: 

http://yaml.org/spec/current.html#id2532720

https://github.com/dotmaster/toYaml/issues/1

Le message d'erreur que je reçois est le suivant:

fatal: [ip.address]: FAILED! => {"changed": false, "cmd": "export 'EXTRA_CONFIG={\"client\":' '{\"subscriptions\":' '[\"DIND-Worker\"],' '\"cluster\":' '\"internal\"}}'", "failed": true, "msg": "[Errno 2] No such file or directory", "rc": 2}
12
user3081519

> démarre un bloc scalaire dans lequel vous n'avez rien à échapper (et aucune séquence d'échappement n'est traitée). En supposant que vous vouliez des guillemets simples autour de votre valeur de type JSON, procédez comme suit:

  - name: Set environment variable
    command: >
      export EXTRA_CONFIG='{"client": {"subscriptions": ["DIND-Worker"], "cluster": "internal"}}'

Edit: Sachez également qu'un scalaire plié inclut par défaut un caractère de fin de ligne. Si vous ne le souhaitez pas, utilisez simplement >- au lieu de >.

15
flyx

Vous utilisez des scalaires de style plié (introduits par >) et, conformément à la spécification YAML 1.2, vous ne pouvez pas échapper des caractères:

Scalaires pliés:

Le style plié est indiqué par l'indicateur «>». C'est semblable au style littéral; Cependant, les scalaires pliés sont sujets au pliage en ligne. 

Et le texte pertinent s’échappe dans des scalaires de style littéral.

Dans les scalaires littéraux, tous les caractères (en retrait) sont considérés comme du contenu, y compris les espaces. Notez que tous les caractères de saut de ligne sont normalisés. De plus, les lignes vides ne sont pas pliées, bien que les lignes finales soient coupées et les lignes vides suivantes soient décomposées. 

D'après votre exemple, vous ne savez pas vraiment ce que vous voulez faire. Vous devriez probablement abandonner le style de pliage au profit du style à double guillemet:

Le style entre guillemets est spécifié par les indicateurs "" "environnants. Il s'agit du seul style capable d'exprimer des chaînes arbitraires, en utilisant des séquences d'échappement"\". personnages. 

ou style simple cité:

Le style entre guillemets simples est spécifié par les indicateurs "'" environnants. Par conséquent, dans un scalaire entre guillemets simples, ces caractères doivent être répétés. C’est la seule forme d’échappement réalisée dans des scalaires à une seule citation. En particulier, les caractères "\" et "" "peuvent être utilisés librement. Ceci limite les scalaires à guillemets simples aux caractères imprimables. -les espaces.

Vous devez donc d’abord décider de ce que le résultat doit être exactement, puis, si vous devez échapper des caractères avec une barre oblique inverse. Si vous ne le faites pas, vous pouvez simplement utiliser un style plié sans style d'échappement, ou un style simple guidé en échappant au ', ou un style double guidé en échappant à " et à tout \. Si vous avez besoin de \, le style entre guillemets doubles est votre seule option.

3
Anthon

Je ne pense pas que cela a quelque chose à voir avec s'échapper. À partir de docs pour command :

Le module de commande prend le nom de la commande suivi d'une liste d'arguments délimités par des espaces. La commande donnée sera exécutée sur tous les nœuds sélectionnés. Il ne sera pas traité par le biais du shell. Par conséquent, les variables telles que $HOME et les opérations telles que "<", ">", "|" et "&" ne fonctionneront pas (utilisez le module Shell si vous avez besoin de ces fonctionnalités).

La commande que vous essayez d'exécuter, export, n'est pas un exécutable; c'est un shell intégré. Il est logique que si Ansible n'exécute pas la commande via un shell, les commandes intégrées à Shell ne sont pas disponibles, par exemple "Aucun fichier ou répertoire de ce type".

Comme le disent les docs, vous pouvez utiliser Shell au lieu de command, mais je ne suis pas sûr que ce soit une solution, car Ansible n'exécutera probablement pas les commandes suivantes dans le même shell, aussi les variables d'environnement que vous avez définies précédemment seront-elles définies. être absent. Voir les réponses à cette question pour des options plus susceptibles de fonctionner: Comment définir des variables d'environnement Linux avec ansible

0
Jordan Running