Qui n'a pas déjà voulu qu'une commande GNU/Linux enregistre son résultat dans le fichier d'origine, genre sort MonFichier > MonFichier
?
Évidemment, ça ne fonctionne pas car, à cause de la redirection (« > »), le shell vide le fichier « MonFichier » puis l'ouvre avec l'identifiant « 1 » (stdout) dans la table des descripteurs de fichiers du processus, puis il se duplique avec l'appel système « fork() » (un fork() conserve la table des descripteurs de fichiers) puis remplace le code de sa copie par celui du programme demandé (sort, dans notre exemple) avec la famille d'appels système « exec() », ce qui en lance l'exécution. Donc, dès le début, le fichier d'origine est vidé.
La plupart des commandes permettent d'écrire leur résultat dans un fichier genre sort -o <fichier> <fichier>
. Mais pas toutes.
C'est là que sponge
intervient : cette commande attend la fin de l'écoulement des données sur stdin puis elle ouvre le fichier passé en argument et enregistre tout ce qu'elle a reçu depuis stdin.
Pratique quand une commande ne permet pas d'enregistrer son travail dans un fichier (genre jq
) et qu'on ne veut pas créer xxx fichiers temporaires (genre « commande fichierN > fichierN+1 »).
Exemple d'utilisation : jq '.' monFichier | sponge monFichier
.