Le Heredoc
Contenu
Le HEREDOC est une structure de bash (mais pas que) très pratique pour passer de multiples lignes d’un seul coup à une commande, ou une fonction.
Exemple :
cat << __EOF__
De
multiples
lignes
__EOF__
Le mot-clef __EOF__
est un délimiteur qui est libre.
N’importe quelle chaine de caractères ascii est utilisable.
Cette structure assez classique cache quelques subtilités que j’ai découvertes récemment. L’occasion parfaite de rédiger ce petit mémo.
Rediriger vers un fichier
Les opérateurs de redirection classiques (>
et >>
), sont utilisables,
et doivent être placés après le délimiteur.
cat << __EOF__ > /etc/ma/super.conf
Clef=valeur
Foo=bar
__EOF__
Passer à une autre commande
On peut également utiliser le pipe |
après le délimiteur pour faire traiter la chaine par une autre commande.
cat << __EOF__ | sed 's/bar/baz'
Clef=valeur
Foo=bar
__EOF__
Fin du fin, on peut aussi rediriger le résultat dans un fichier. En fait la ligne après le délimiteur est à voir comme une ligne de commande classique.
cat << __EOF__ | sed 's/bar/baz/' > /etc/ma/super.conf
Clef=valeur
Foo=bar
__EOF__
Avec des variables
De base, les substitutions sont actives dans le contenu du HEREDOC :
cat << __EOF__ > /etc/ma/super.conf
Hostname=$HOSTNAME
Foo=bar
__EOF__
Mais il peut arriver que l’on ne veuille pas les substituer dans le fichier final,
pour conserver le symbole $
.
Oui, je pense à toi là, systemd … Et pour faire ça …
Sans variables
Il suffit d’entourer de guillemets le premier délimiteur :
cat << '__EOF__' > /etc/ma/super.conf
Hostname=$HOSTNAME
Foo=bar
__EOF__
Cela fonctionne également avec des guillemets doubles.
Si vous souhaitez être économe en caractères, échapper le délimiteur est également faisable (merci @breizh pour cette astuce) :
cat << \__EOF__ > /etc/ma/super.conf
Hostname=$HOSTNAME
Foo=bar
__EOF__
Une dernière méthode, un peu plus pénible cela dit si vous avez beaucoup de variables,
consiste à échapper le $
pour empêcher sa substitution.
Il ne faut alors plus mettre de guillemets autour du délimiteur :
cat << __EOF__ > /etc/ma/super.conf
Hostname=\$HOSTNAME
Foo=bar
__EOF__
Un peu d’indentation ?
Si vous souhaitez indenter le contenu de vos Heredocs dans vos scripts
sans que cela n’ait d’incidence sur les commandes qui vont le récupérer,
l’opérateur de redirection devient <<-
.
Oui, l’opérateur classique <<
immédiatement suivi d’un tiret : -
.
Les tabulations en début de ligne seront automatiquement supprimées par Bash à l’interprétation.
cat <<- __EOF__
De
multiples
lignes
indentées
avec
des
tabulations
sans
aucun
effet
au
final
__EOF__
De
multiples
lignes
indentées
avec
des
tabulations
sans
aucun
effet
au
final
Vous pourrez même indenter le délimiteur de fin.