6 votes

Bash script pour limiter la taille d'un répertoire en supprimant les fichiers accédés en dernier.

J'avais auparavant utilisé une simple commande find pour supprimer les fichiers tar non consultés au cours des x derniers jours (dans cet exemple, 3 jours) :

find /PATH/TO/FILES -type f -name "*.tar" -atime +3 -exec rm {} \;

Je dois maintenant améliorer ce script en supprimant par ordre de date d'accès et mes compétences en écriture bash sont un peu rouillées. Voici ce que j'ai besoin qu'il fasse :

  1. vérifier la taille d'un répertoire /PATH/TO/FILES
  2. si la taille en 1) est supérieure à la taille X, obtenir une liste des fichiers par date d'accès
  3. supprimer les fichiers dans l'ordre jusqu'à ce que la taille soit inférieure à X

L'avantage ici est que pour les répertoires de cache et de sauvegarde, je ne supprimerai que ce dont j'ai besoin pour rester dans une limite, alors que la méthode simplifiée pourrait dépasser la limite de taille si un jour est particulièrement important. Je suppose que je dois utiliser stat et une boucle for bash ?

10voto

Lari Hotari Points 1960

J'ai amélioré l'exemple de Brunner314 et corrigé les problèmes qu'il contenait.

Voici un script fonctionnel que j'utilise :

#!/bin/bash
DELETEDIR="$1"
MAXSIZE="$2" # in MB
if [[ -z "$DELETEDIR" || -z "$MAXSIZE" || "$MAXSIZE" -lt 1 ]]; then
    echo "usage: $0 [directory] [maxsize in megabytes]" >&2
    exit 1
fi
find "$DELETEDIR" -type f -printf "%T@::%p::%s\n" \
| sort -rn \
| awk -v maxbytes="$((1024 * 1024 * $MAXSIZE))" -F "::" '
  BEGIN { curSize=0; }
  { 
  curSize += $3;
  if (curSize > maxbytes) { print $2; }
  }
  ' \
  | tac | awk '{printf "%s\0",$0}' | xargs -0 -r rm
# delete empty directories
find "$DELETEDIR" -mindepth 1 -depth -type d -empty -exec rmdir "{}" \;

5voto

user690750 Points 191

Voici une méthode simple, facile à lire et à comprendre, que j'ai mise au point pour y parvenir :

DIRSIZE=$(du -s /PATH/TO/FILES | awk '{print $1}')
if [ "$DIRSIZE" -gt "$SOMELIMIT" ]
  then
    for f in `ls -rt --time=atime /PATH/TO/FILES/*.tar`; do
    FILESIZE=`stat -c "%s" $f`
    FILESIZE=$(($FILESIZE/1024))

    DIRSIZE=$(($DIRSIZE - $FILESIZE))
    if [ "$DIRSIZE" -lt "$LIMITSIZE" ]; then
        break
    fi
done
fi

1voto

brunner314 Points 111

Je n'ai pas eu besoin d'utiliser des boucles, juste une application prudente de stat et awk. Détails et explications ci-dessous, d'abord le code :

find /PATH/TO/FILES -name '*.tar' -type f \
| sed 's/ /\\ /g' \
| xargs stat -f "%a::%z::%N" \
| sort -r \
| awk '
  BEGIN{curSize=0; FS="::"}
  {curSize += $2}
  curSize > $X_SIZE{print $3}
  '
| sed 's/ /\\ /g' \
| xargs rm

Notez que c'est une ligne de commande logique, mais pour des raisons de bon sens, je l'ai séparée.

Elle commence par une commande find basée sur celle ci-dessus, sans les parties qui la limitent aux fichiers de plus de 3 jours. Elle passe cette commande à sed, pour échapper aux espaces dans les noms de fichiers retournés par find, puis utilise xargs pour lancer stat sur tous les résultats. Le -f "%a::%z::%N" indique à stat le format à utiliser, avec l'heure du dernier accès dans le premier champ, la taille du fichier dans le second, et le nom du fichier dans le troisième. J'ai utilisé '::' pour séparer les champs car il est plus facile de traiter les espaces dans les noms de fichiers de cette façon. Sort les trie ensuite sur le premier champ, avec -r pour inverser l'ordre.

Nous avons maintenant une liste de tous les fichiers qui nous intéressent, dans l'ordre du dernier accès au plus ancien. Ensuite, l'awk script additionne toutes les tailles au fur et à mesure qu'il parcourt la liste, et commence à les sortir quand il dépasse $X_SIZE. Les fichiers qui ne sont pas sortis de cette façon seront ceux conservés, les autres noms de fichiers vont à sed à nouveau pour échapper aux espaces et ensuite à xargs, qui les exécute rm.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X