Linux / Commande truncate : réduire ou agrandir la taille d’un fichier

truncate fixe ou ajuste la taille logique d’un fichier : le réduire supprime les données situées après la nouvelle fin, tandis que l’allonger ajoute une zone qui se lit comme des octets nuls. La commande conserve le fichier lui-même et crée normalement un fichier absent ; travaillez sur une copie si le contenu compte, car revenir à l’ancienne taille ne restaure pas les données coupées.

Ce guide utilise GNU truncate. La taille logique, visible avec stat ou ls -l, est distincte de l’espace effectivement alloué au stockage. Un fichier agrandi n’est ni un test d’écriture complète de cette capacité ni une réservation garantie de tout cet espace.

Réduire une copie et vérifier les octets restants

Commencez dans un nouvel espace temporaire. Ces commandes créent un original de 10 octets et une copie, puis réduisent uniquement la copie :

espace=$(mktemp -d) || exit 1
printf 'ABCDEFGHIJ' > "$espace/original.bin"
cp -- "$espace/original.bin" "$espace/essai.bin" || exit 1
truncate -s 4 -- "$espace/essai.bin" || exit 1
printf 'ABCD' > "$espace/attendu.bin"
cmp -- "$espace/attendu.bin" "$espace/essai.bin" || exit 1
stat -c '%s' -- "$espace/essai.bin"
printf 'Espace de travail : %s\n' "$espace"

cmp reste silencieux si la copie contient exactement ABCD, puis stat affiche 4. L’original contient toujours ABCDEFGHIJ. Conservez la variable espace pour les essais suivants et inspectez ce dossier avant de le nettoyer.

truncate -s 10 -- "$espace/essai.bin"
stat -c '%s' -- "$espace/essai.bin"

La copie retrouve une taille de 10 octets, mais pas son ancien contenu : les six octets après ABCD se lisent comme des zéros, pas comme EFGHIJ. Si vous voulez retrouver le contenu initial, repartez de l’original ou d’une sauvegarde, puis vérifiez les octets avec cmp.

Sur Linux, changer la longueur ne retire pas l’entrée du répertoire. L’opération peut mettre à jour les dates de modification et de changement de métadonnées ; certains bits de mode spéciaux peuvent être supprimés. Les détails d’accès et d’extension dépendent du système de fichiers et des droits, comme l’explique la documentation Linux de truncate et ftruncate.

Fixer une taille, ajouter ou retirer une quantité

truncate -s 0 -- "$espace/vide.bin"
truncate -s 1M -- "$espace/un-mio.bin"
truncate -s +2 -- "$espace/essai.bin"
truncate -s -3 -- "$espace/essai.bin"
stat -c '%s %n' -- "$espace/vide.bin" "$espace/un-mio.bin" "$espace/essai.bin"

Les tailles finales de ces trois fichiers sont 0, 1 048 576 et 9 octets : essai.bin avait retrouvé 10 octets, puis a gagné 2 et perdu 3. Le signe moins de -3 appartient ici à la valeur attendue par -s. --size=-3 est une autre écriture explicite.

Dans GNU, M et MiB signifient 1 048 576 octets, tandis que MB signifie 1 000 000 octets. K et KiB signifient 1 024 octets, contre 1 000 pour KB. Évitez de mélanger ces notations lorsque vous calculez une limite exacte.

Protégez les variables par des guillemets et mettez -- avant les noms qui pourraient commencer par un tiret. Une taille et un nom sont deux arguments distincts ; ne laissez pas un espace ou un motif dans le nom être interprété par le shell.

Appliquer un plafond, un minimum ou un arrondi

Valeur de -s Règle Exemple depuis 10 octets
6 Fixer exactement 6 octets
+6 Ajouter 16 octets
-6 Retirer 4 octets
'<6' Ne pas dépasser le plafond 6 octets
'>6' Atteindre au moins le minimum 10 octets
/4 Arrondir vers le bas à un multiple 8 octets
%4 Arrondir vers le haut à un multiple 12 octets
cp -- "$espace/original.bin" "$espace/plafond.bin"
cp -- "$espace/original.bin" "$espace/minimum.bin"
truncate -s '<6' -- "$espace/plafond.bin"
truncate -s '>6' -- "$espace/minimum.bin"
stat -c '%s %n' -- "$espace/plafond.bin" "$espace/minimum.bin"

Le plafond ramène la copie à 6 octets ; le minimum laisse l’autre à 10. Les guillemets autour de < et > sont indispensables pour éviter que le shell les traite comme des redirections. Un plafond ou un arrondi vers le bas reste une opération destructrice lorsque le fichier doit rétrécir.

Éviter la création et utiliser un fichier de référence

truncate -c -s 0 -- "$espace/absent.bin"
if [ ! -e "$espace/absent.bin" ]; then
  printf '%s\n' 'Aucun fichier créé'
fi

-c, ou --no-create, laisse une cible absente sans la créer. Ce cas peut réussir avec un statut 0 : ce statut ne prouve donc pas que le fichier existe ou a été modifié. Si l’existence est une condition de votre travail, contrôlez-la explicitement selon le type d’objet et l’opération voulus.

printf '123456' > "$espace/reference.bin"
printf 'abcdefghij' > "$espace/cible.bin"
truncate --reference="$espace/reference.bin" -- "$espace/cible.bin"
stat -c '%s %n' -- "$espace/reference.bin" "$espace/cible.bin"

Les deux tailles deviennent 6, mais la cible contient abcdef, pas 123456. -r ou --reference prend la taille de référence sans copier son contenu. Une référence indisponible est une erreur ; ne confondez pas égalité de tailles et égalité de données.

Comparer taille logique et espace alloué

stat -c 'taille=%s blocs=%b unite_bloc=%B' -- "$espace/un-mio.bin"
du -B1 -- "$espace/un-mio.bin"
du --apparent-size -B1 -- "$espace/un-mio.bin"

La taille logique doit être 1 048 576 octets. L’extension peut être représentée par des trous, aussi appelés zones creuses ou sparse, qui se lisent comme des zéros sans avoir un bloc alloué pour chaque octet logique. Les résultats d’allocation dépendent du système de fichiers ; n’attendez pas un nombre de blocs universel.

Dans stat, %b est un nombre de blocs et %B indique la taille de leur unité. L’espace de transfert préféré %o est encore une autre information. Le guide de stat et les mesures de du expliquent ces distinctions. La compression, les blocs partagés et les outils de copie peuvent aussi influer sur l’occupation observée.

truncate -o, ou --io-blocks, change précisément l’unité du réglage de taille : celle-ci devient un nombre de blocs d’entrée-sortie du fichier, plutôt que des octets. N’activez pas cette option en supposant qu’un bloc vaut toujours 4 Kio.

truncate -s 0 -- "$espace/io.bin"
stat -c 'unite_io=%o' -- "$espace/io.bin"
truncate -o -s 2 -- "$espace/io.bin"
stat -c 'taille=%s' -- "$espace/io.bin"

La taille demandée est deux fois l’unité d’entrée-sortie du fichier. Elle peut donc différer selon l’environnement. Les suffixes et modes sont décrits dans le manuel GNU de truncate ; utilisez la taille en octets sans -o lorsque vous voulez un résultat indépendant de cette unité.

Redimensionner une nouvelle copie avec un script complet

Le script suivant exige une taille entière en octets, crée un nouvel espace privé puis copie la source avant de redimensionner cette copie. Enregistrez-le sous redimensionner-copie.sh. Il nécessite Bash, GNU mktemp, cp, stat et truncate ; il ne modifie pas la source indiquée.

#!/usr/bin/env bash
if [ "$#" -ne 2 ]; then
  printf '%s\n' 'Usage : bash redimensionner-copie.sh fichier taille-en-octets' >&2
  exit 64
fi
case "$2" in
  ''|*[!0-9]*)
    printf '%s\n' 'La taille doit être un entier non négatif en octets.' >&2
    exit 64 ;;
esac
if [ ! -f "$1" ]; then
  printf '%s\n' 'La source doit être un fichier ordinaire.' >&2
  exit 66
fi
umask 077
espace=$(mktemp -d) || exit "$?"
copie=$espace/copie.bin
cp -- "$1" "$copie" || exit "$?"
avant=$(stat -c '%s' -- "$copie") || exit "$?"
truncate --size="$2" -- "$copie" || {
  statut=$?
  printf 'Échec ; copie à examiner : %q\n' "$copie" >&2
  exit "$statut"
}
apres=$(stat -c '%s' -- "$copie") || exit "$?"
printf 'Avant : %s octets\nAprès : %s octets\nCopie : %q\n' "$avant" "$apres" "$copie"
bash redimensionner-copie.sh "$espace/original.bin" 4

L’affichage indique 10 octets avant, 4 après et le chemin de la nouvelle copie, qui contient ABCD pour cet exemple. Le statut 64 correspond aux arguments incorrects, 66 à une source qui n’est pas un fichier ordinaire ; une erreur d’outil conserve son propre statut. Une copie ou un dossier temporaire peut rester après un échec : inspectez le chemin avant nettoyage.

Le contrôle -f et la copie sont séparés. Cette méthode convient à un fichier que vous choisissez et gardez stable, pas à un service privilégié qui accepte des chemins non fiables. La copie de travail ne remplace pas une sauvegarde indépendante pour des données importantes.

Savoir quand truncate ne répond pas au besoin

  • Effacer confidentiellement des données : fixer la taille à 0 ne prouve pas que les anciens blocs, snapshots ou sauvegardes ont été effacés.
  • Préparer une vraie capacité d’écriture : une extension creuse ne démontre ni l’espace disponible à terme ni les performances d’écriture. Le guide de dd distingue écriture de données et taille logique.
  • Agrandir un format structuré : augmenter un fichier image n’agrandit pas automatiquement les partitions, le système de fichiers ou la base de données à l’intérieur.
  • Gérer un journal actif : tronquer le fichier ne réinitialise pas forcément la position d’écriture détenue par un processus. Une nouvelle écriture peut faire réapparaître un fichier long ou une zone creuse ; utilisez la procédure de rotation et de réouverture prévue pour le service.

truncate ne verrouille pas à lui seul les autres écrivains et ne constitue pas un lot atomique pour plusieurs fichiers. Vérifiez la bonne cible, l’absence d’écritures concurrentes, les tailles attendues et les octets importants. Pour retrouver une fin de fichier supprimée, la bonne procédure est une restauration depuis une copie conservée, suivie d’une comparaison ; augmenter seulement la longueur ne suffit pas.