URL:     https://linuxfr.org/users/n_e/journaux/ecrire-du-json-dans-un-script-bash
Title:   Écrire du JSON dans un script bash
Authors: n_e
Date:    2026-10-13T18:13:14+02:00
Tags:    
Score:   2


J'ai toujours galéré à quoter et échapper correctement les chaînes de caractères compliquées avec bash, donc je me suis dit que j'allais (enfin) regarder la doc.

Je parle de JSON dans le titre, qui est particulièrement pénible car il contient beaucoup de guillemets, mais ça s'applique aussi aux quotes l'une dans l'autre, typiquement quand on veut exécuter une sous-commande. Par exemple un one-liner dans un autre langage de programmation, ou une commande avec ssh ou un sous-shell.

Commençons par regarder les 4 mécanismes de quoting intéressants dans bash, on passera ensuite à des exemples.

# Les mécanismes

## 1. Les apostrophes

C'est le plus simple à expliquer : tout ce qui est entre des apostrophes est traité comme un caractère normal, à l'exception d'un \ suivi d'un retour à la ligne, qui ignore ce retour à la ligne.

Une conséquence pénible de ce fonctionnement est qu'il est impossible de mettre une apostrophe dans ce type de chaîne. Une façon moche de contourner ça est de fermer l'apostrophe, l'échapper puis la rouvrir :

```sh
echo 'l'\''animal'
```

A noter que la commande `echo` de zsh interprète par défaut les caractères d'échappement commençant par \, ce qui peut donner à tort l'impression que les chaînes entre apostrophes le font.

## 2. les guillemets

Ils interprètent les séquences commençant par $ (variables, etc.), les séquences avec `\` et les apostrophes inversées (commandes).

C'est souvent le plus pratique, mais l'inconvénient est que pour les formats comme le JSON, il faut échapper beaucoup de guillemets.

## 3. Le quoting ANSI-C

Celui-ci je ne le connaissais pas : c'est la même chose que les guillemets simples, mais il interprète les séquences en \ :

```sh
echo $'l\'animal'
```

C'est vraiment pratique, car ça permet de faire la même chose que des guillemets simples, mais avec la possibilité de mettre des guillemets simples facilement, ou d'autres caractères spéciaux comme les tabulations ou les retours à la ligne.

## 4. Les here docs

Ce n'est pas un mécanisme de quoting, mais sert à indiquer une chaîne de caractères qui va être envoyé sur stdin. Il est très pratique pour des chaînes de caractères de plusieurs lignes, et on peut tricher pour l'utiliser pour le quoting :

```sh
# Ecrit le here document dans fichier.txt
cat > fichier.txt <<EOF
Ligne 1
Ligne 2
EOF

# On triche pour le quoting
echo $(<<EOF
Ligne 1
Ligne 2
EOF
)
```

À noter que EOF est une chaîne de caractères arbitraire : on peut utiliser n'importe quelle chaîne qui ne sera pas une ligne du here document.

# En pratique

## Sans variables

Admettons que l'on veuille consulter une API de météo. Commençons par la façon pénible de faire :

```sh
curl --json '{"city": "L'\''Isle d'\''Abeau"}' https://example.com/weather
```

Maintenant, avec ce qu'on a appris on peut utiliser le quoting ANSI-C :

```sh
curl --json $'{"city": "L\'Isle d\'Abeau"}' https://example.com/weather
```

Ou les here documents :

```sh
curl --json @- https://example.com/weather <<EOF
{"city": "L'Isle d'Abeau"}
EOF
```

Note : @- est une option spécifique à curl lui disant de lire les données sur stdin.

## Avec des variables

Commençons cette fois-ci aussi par la façon pénible de faire. Vu qu'on ne peut pas utiliser des variables avec des apostrophes, utilisons des guillemets :

```sh
curl --json "{\"city\":\"$CITY\"}" https://example.com/weather
```

On peut faire mieux avec un here document :

```sh
curl --json @- https://example.com/weather <<EOF
{"city": "$CITY"}
EOF
```

Ou avec des guillemets simples et printf :

```sh
printf '{"city":"%s"}' "$CITY" | curl --json @- https://example.com/weather <<EOF
```

Ou, si on veut une solution qui marche avec une ville arbitraire pouvant contenir des guillemets dans son nom :

```sh
jq -n '{city: $CITY}' --arg CITY "$CITY" | curl --json @- https://example.com/weather <<EOF
```
