2016-05-25 60 views
5

Ho bisogno di evadere correttamente le virgolette singole e doppie in un playbook ansibile per impostare la variabile di ambiente. Niente di tutto questo funziona:Come evitare le virgolette doppie e singole in YAML all'interno della stessa stringa

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

hanno guardato questo:

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

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

Il messaggio di errore che ottengo è:

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} 
+0

Si può provare a utilizzare 'shell' invece del modulo' command'? È quindi possibile eseguire l'escape tramite '\" '. Se si ha solo bisogno di env vars su una base per attività, si potrebbe anche considerare l'uso della funzione' environment' di 'shell' come descritto [qui] (http://stackoverflow.com/questions/31775099/how-to-set-environmental-variables-using-ansible) – fishi

risposta

5

> inizia uno scalare blocco, in cui non hai bisogno di e scape nulla (e non ci sono sequenze di escape elaborate). Quindi, supponendo che si desidera apici intorno alla vostra valore JSON-like, basta fare:

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

Edit: Anche essere consapevoli che uno scalare piegato per default include un carattere finale di nuova riga. Se non si desidera avere questo, basta usare >- anziché >.

+0

Funziona davvero per te? Nel mio caso mi piacerebbe ancora ottenere '[Errno 2] Nessun file o directory di questo tipo. 'possibile attraverso il modulo' command'? – fishi

+1

Beh, ho risposto in base alla mia conoscenza di YAML, non so ansible, ma suppongo che il comando venga eseguito in un'istanza di shell isolata, quindi esportare qualcosa qui non influirà Se vuoi impostare una variabile di ambiente globale, devi metterla in '/ etc/environment' o qualcosa di simile. – flyx

+0

Buon punto: hai ragione, ogni attività aprirà una nuova shell, il che significa che l'env var non è persistente in tutto il gioco tranne che lo si inserisce in un file dedicato sul nodo proveniente dalla shell o esplicitamente impostato per ogni attività, ad esempio utilizzando la funzione 'environment' del modulo' shell' di ansible. – fishi

2

si utilizza scalari stile piegati (introdotte dalla >) e secondo le specifiche YAML 1.2 non si può sfuggire caratteri:

scalari Piegato:

Lo stile ripiegato è segnato con il “>” indicatore. È simile allo stile letterale; tuttavia, gli scalari piegati sono soggetti al piegamento della linea.

E il testo pertinente che sfugge agli scalari di stile letterale.

All'interno di scalari letterali, tutti i caratteri (rientranti) sono considerati come contenuti, compresi i caratteri dello spazio bianco. Si noti che tutti i caratteri di interruzione di riga sono normalizzati. Inoltre, le linee vuote non vengono piegate, anche se le interruzioni di riga finale e le linee vuote vengono tritate.

Dal tuo esempio non è chiaro cosa vuoi veramente fare. Probabilmente si dovrebbe cadere stile pieghevole a favore della doppia stile citato:

Lo stile doppio citato è specificato da circostante “"”. Gli indicatori Questo è l'unico stile capace di esprimere stringhe arbitrarie, utilizzando‘\’fuga sequenze, a costo di dover sfuggire ai caratteri "\" e "" ".

o unico stile citato:

Lo stile unico citato è specificata circondando “'” indicatori. Pertanto, all'interno di uno scalare con quotatura singola, tali caratteri devono essere ripetuti. Questa è l'unica forma di escape eseguita in scalari con quotatura singola. In particolare, i caratteri "\" e "" "possono essere usati liberamente, in modo da limitare gli scalari con quotatura singola ai caratteri stampabili. Inoltre, è possibile solo rompere una linea lunga con quotatura singola in cui un carattere spazio è circondato da non -spaces.

Quindi si dovrebbe prima decidere quale deve essere esattamente l'uscita, quindi se è necessario sfuggire a qualsiasi carattere con barra rovesciata. Se non lo fai, puoi semplicemente usare lo stile piegato senza stile di escape o singolo quotato sfuggendo allo stile ' o doppio quotato sfuggendo allo " ea qualsiasi \. Se ti serve lo stile di escape \ è la tua unica opzione.

+0

Puoi chiarire la tua frase? 'Se hai bisogno di \ escape lo stile double quoted è la tua unica opzione. Con le virgolette singole, non devi uscire da' \ '. Perché le virgolette singole non sono un'opzione se è necessario includere '\' in una stringa? –

+0

Se hai bisogno di "\" escape significa che devi inserire uno dei [caratteri di escape] (http://www.yaml.org/spec/1.2/spec.html#id2776092) che hanno bisogno di una barra rovesciata. Non è possibile inserirli in stringhe scalari con quotatura singola. In quel contesto parlare di citazioni singole è irrilevante. – Anthon

+0

Capisco. Vuoi dire se è necessario aggiungere cose come '\ n',' \ t', deve usare le virgolette. Nelle virgolette singole il backslash non ha alcun significato speciale.Né le sequenze di escape come '\ n',' \ t', e così via. –

0

Non penso che questo abbia nulla a che fare con l'evasione. Da docs for command:

Il modulo di comando accetta il nome del comando seguito da un elenco di argomenti delimitati da spazi. Il comando dato verrà eseguito su tutti i nodi selezionati. Non verrà elaborato tramite la shell, quindi variabili come $HOME e operazioni come "<", ">", "|" e "&" non funzioneranno (utilizzare il modulo shell se sono necessarie queste funzionalità).

Il comando che si sta tentando di eseguire, export, non è un eseguibile; è una shell integrata. Ha senso che se Ansible non sta eseguendo il comando attraverso una shell che i builtin di shell non sono disponibili, ergo "Nessun file o directory di questo tipo".

Come i documenti dire, è possibile utilizzare al posto di shellcommand, ma non sono sicuro che questa è una soluzione, perché Ansible probabilmente non viene eseguito comandi successivi nella stessa shell, in modo che qualsiasi variabili di ambiente si determinati in precedenza essere assente. Vedere le risposte a questa domanda per alcune opzioni che hanno maggiori probabilità di funzionare: How to set linux environment variables with ansible