1.1 Recherche de sushi
La solution est ma foi assez simple et repose sur l'utilisation de
find avec -perm et -user dans le prédicat. La
ligne de commande suivant montre comment supprimer de tels fichiers, en se
basant sur le fait que les répertoires des utilisateurs sont
situés sous /home
find /home \(-user root -o -user bin \) -perm -4111
-exec rm {} \;
1.2 Utilisation conjointe de tar, find et
xargs
Il n'est guère compliqué de rechercher les fichiers
correspondant aux conditions :
- Fichier .c ou .h : -name "*.c" -o -name
"*.h" En outre, et afin que cette expression soit
évaluée indépendamment des autres, il sera
nécessaire de l'intégrer dans un groupe en l'entourant de
parenthèses. Toutefois, les parenthèses ayant une signification
particulière pour les shells, il sera indispensable de les faire
précéder d'une barre oblique inverse, soit : \( -name
"*.c" -o -name "*.h" \) Je recommande également
de toujours laisser un espace après la parenthèse ouvrante et un
autre avant le \.
- Fichier véritable : -type f ceci permet de ne
pas suivre les liens symboliques sur les répertoires et les fichiers.
L'utilisation d'archives avec des liens symboliques étant quelque peu
technique, nous vous recommandons de consulter le manuel à ce sujet
- Date de modification supérieure à 30 jours :
-mtime +30
- Date de changement supérieure à 6 jours :
-ctime +6
Nous obtenons finalement l'expression suivante que, dans la suite de
l'exercice, nous appellerons A :
find . -type f -mtime +30 -ctime +6 \( -name "*.c" -o -name "*.h"\) -print
Passons désormais à la partie archivage :
- Première solution (marche pour un petit nombre de
fichiers) :
tar cvf archive.tar `A`
- Deuxième solution (horriblement lente) :
rm -f archive.tar
touch archive.tar
find -type f -mtime +30 -ctime +6 \( -name "*.c" -o -name "*.h"\) -exec tar rvf archive.tar {} \;
- Troisième solution (la seule correcte) :
rm -f archive.tar
touch archive.tar
A | xargs ./auxiliaire archive.tar
Constitution du script temporaire nommé auxiliaire
#!/bin/ksh
ARCHIVE=${1}
shift
if [[ -f ${ARCHIVE} ]]
then
tar rvf ${ARCHIVE} $*
else
tar cvf ${ARCHIVE} $*
fi
Cet exercice est mon préféré ! En effet, il permet
de faire, avec quelques astuces, des opérations délicates
très efficacement !
- Constitution d'une archive et compression à la
volée :
tar cvf - rep | compress -9 - > archive.tar.Z
La décompression et le désarchivage se font alors gràce
à :
zcat archive.tar.Z | tar xvfp -
où, si l'on utilise gzip ou bzip2 (même
syntaxe) :
tar cvf - rep | gzip -9 - > archive.tar.gz
gzip -d -c archive.tar.gz | tar xvfp -
Par soucis de complétude, notons l'option z du tar de Linux qui permet
d'intégrer la (dé)compression sans connecteur
supplémentaire !
- Je décide de travailler avec gzip :
tar cvf - rep | gzip -9 - | uuencode archive.tar.gz archive.tar.gz | mail
-s "voila ton répertoire mon paulo !"
- Ici il faut utiliser un sous-shell (c'est à dire l'exécution
d'une commande par un shell différent pour bien réaliser
l'opération !)
Supposons que vous disposiez de l'arborescence suivante :
Et que vous souhaitiez transférer la sous arborescende de r3
vers v2, voici la solution à partir de /home :
cd v1
tar cvf - r3 | (cd /home/v2 ; tar xvfp -)
Etant irrémédiablement bavard, je me permets un petit
commentaire sur le gain de place disque engendré, par exemple, par la
décompaction / désarchivage en une seule
opération. En effet, supposons que vous récupériez par
ftp un fichier .tar.gz disons de 8Mo, contenant, par exemple,
le code source de gcc. Si vous le décompressez avant de le
désarchiver, vous avez besoin de stocker sur le disque le fichier tar
décompressé avant de récupérer les fichiers eux
mêmes ce qui peut suffire à combler votre partition !
L'expression régulière à construire est la
suivante :
'(^|_)[([{]*[lL]apin[]{).,;]*(_|$)'
où nous avons remplacé le caractère espace par un
souligné.
Ceci peut vous paraître compliqué mais se révèle
en fait fort simple :
- Le mot lapin peut commencer par une minuscule ou une majuscule :
[lL]apin
- Il peut être entouré de signes éventuels de
ponctuations :
- Avant ce sera nécessairement une parenthèse, un crochet ou
une accolade, d'où la classe :[([{] Notez que cette classe
contient elle même un crochet qui est banalisé dès qu'il se
trouve dans une classe
- Après, ce pourra être une parenthèse fermante, un
crochet fermant , une accollade fermante ou une virgule, un point etc ...
d'où la classe : []{).,;] Vous notez qu'il y a un crochet
fermant dans la classe alors que ce caractère est sensé fermer la
classe ! Il s'agit d'une convention propre à unix. Un
caractère crochet fermant placé en première position dans
une classe devient banalisé.
- Il ne reste plus qu'à spécifier que la ponctuation peut
être répétée de 0 à plusieurs fois
(d'où les étoiles) et qu'il y a nécessairement :
- soit un espace soit le début de ligne avant, l'expression commence
donc par (^|_)
- soit un espace soit la fin de ligne après, l'expression se termine
donc par (_|$)