Pages : 1
#1 Le 25/06/2008, à 23:29
- sebk
bug entre tar et xargs [résolus]
Bonjour,
Je suis en train de réaliser un script de sauvegarde des différents homes de mon ubuntu sur un serveur ftp distant (ma freebox en fait).
Tout est au point sauf un petit détail : lorsqu'un fichier contiends un double espace (notament des sauvegardes de page web), tar concatène les deux espace en un seul et ne trouve donc pas le fichier.
J'ai bien trouvé un moyen de contourner ça en mettant des quotes mais le soucis c'est que pour créer la commande, je suis obligé d'utiliser un xargs pour exploiter le résultat de la commande find.
Petite précision pour ceux qui me répondrons que je n'ai qu'à faire un tar d'un répertoire tout simplement, c'est que j'ai des règles d'exception paramétrable et que je retravail donc le résultat du find.
La commande que j'utilise est la suivante :
sudo -u $usersb cat /tmp/save_fichiers.log | xargs tar -rf /tmp/$nom_archive.tar 2> /tmp/save_tar.log
Quelqu'un aurait-il une idée de comment je peux contourner cela ?
Dernière modification par sebk (Le 10/07/2008, à 22:44)
Iceberg Project : www.iceberg-linux.net
Hors ligne
#2 Le 26/06/2008, à 12:09
- Totor
Re : bug entre tar et xargs [résolus]
peux-tu poster ta commande initiale (find + tar) ?
-- Lucid Lynx --
Hors ligne
#3 Le 26/06/2008, à 17:54
- sebk
Re : bug entre tar et xargs [résolus]
Voici mon script complet
#!/bin/bash
renice -20 $$
if [ "$1" != "" ]
then
config="$1"
else
config="/home/seb/.script/save.conf"
fi
config=`echo $config | sed "s/ /\\\ /g"`
if [ ! -f $config ]
then
echo "`date` : Lecture des paramètres impossible" > save.log
exit 1
fi
echo "`date` : Lecture des paramètres..." > save.log
# lecture du nom de l'archive
usersb=`bash /home/seb/.script/config_reader.sh "$config" user`
if [ "$usersb" = "" ]
then
usersb="root"
fi
echo "substitution : $usersb"
# lecture des répertoires à sauvegarder
bash /home/seb/.script/config_reader.sh $config save-path > /tmp/save_path.tmp
# lecture des trames de fichier à exclure
bash /home/seb/.script/config_reader.sh $config exclude > /tmp/save_exclude.tmp
# lecture des trames à inclure malgrès tout
bash /home/seb/.script/config_reader.sh $config force-include > /tmp/save_include.tmp
# lecture du nom de l'archive
nom_archive=`bash /home/seb/.script/config_reader.sh $config nom-archive`
if [ "$nom_archive" = "" ]
then
exit 1
fi
# lecture de la chaine de connexion
site=`bash /home/seb/.script/config_reader.sh $config site`
if [ "$nom_archive" = "" ]
then
exit 1
fi
#site=`echo $site | sed "s/ /\\\ /"`
echo "`date` : Début du traitement de sauvegarde" > save.log
# raz log des fichiers
echo "" > /tmp/save_fichiers.log
# raz de l'archive si elle existe
rm /tmp/$nom_archive.tar
# archivage de la dernière archive valide
parm="$site"
i=0
user=""
password=""
server=""
path=""
tmp=""
if [ -f "/tmp/ok_$nom_archive" ]
then
# décomposition du paramètre
while [ $i -lt ${#parm} ]
do
# récuparation du user
if [ "$user" = "" ]
then
if [ "${parm:i:1}" != ":" ]
then
tmp="$tmp${parm:i:1}"
else
user="$tmp"
tmp=""
i=`expr $i + 1`
fi
fi
# récuparation du mot de passe
if [ "$user" != "" -a "$password" = "" ]
then
if [ "${parm:i:1}" != "@" ]
then
tmp="$tmp${parm:i:1}"
else
password="$tmp"
tmp=""
i=`expr $i + 1`
fi
fi
# récuparation du serveur
if [ "$user" != "" -a "$password" != "" -a "$server" = "" ]
then
if [ "${parm:i:1}" != "/" ]
then
tmp="$tmp${parm:i:1}"
else
server="$tmp"
tmp=""
fi
fi
# récuparation du fichier
if [ "$user" != "" -a "$password" != "" -a "$server" != "" ]
then
path="$path${parm:i:1}"
fi
i=`expr $i + 1`
done
ftp -nv $server << SCRIPT
quote user $user
quote pass $password
delete "$path/$nom_archive.tar.gz.old"
rename "$path/$nom_archive.tar.gz" "$path/$nom_archive.tar.gz.old"
quit
SCRIPT
rm -f "/tmp/ok_$nom_archive"
fi
# pour chaque répertoire
while read rep
do
sudo -u $usersb find $rep | sed "s/\\\\/\\\\\\\\/g" | sed "s/\\ /\\\\ /g" > /tmp/save_find.tmp
# pour chaque fichier
while read fichier
do
if [ -f "$fichier" ]
then
exclusion="non"
# test la trame d'exclusion
while read exclus
do
if [ "`echo $fichier | sed -n \"/$exclus/p\"`" != "" ]
then
exclusion="oui"
fi
done < /tmp/save_exclude.tmp
# test si la trame est à inclure malgrès tout
while read inclus
do
if [ "`echo $fichier | sed -n \"/$inclus/p\"`" != "" ]
then
exclusion="non"
fi
done < /tmp/save_include.tmp
# si le fichier n'est pas exclus
if [ "$exclusion" = "non" ]
then
# Création de la liste des fichiers
fichier=`echo $fichier | sed "s/\"/\\\\\"/g"`
echo "\"$fichier\"" >> /tmp/save_fichiers.log
fi
fi
done < /tmp/save_find.tmp
done < /tmp/save_path.tmp
# création de l'archive
rm -f /tmp/$nom_archive.tar
sudo -u $usersb cat /tmp/save_fichiers.log | xargs tar -rf /tmp/$nom_archive.tar 2> /tmp/save_tar.log
cat /tmp/save_tar.log | grep -v "tar: Suppression de « / » au début des noms des membres" >> /tmp/save.log
# compression
echo "`date` : Début de la compression de l'archive" >> /tmp/save.log
rm /tmp/$nom_archive.tar.gz
gzip -9 /tmp/$nom_archive.tar 2>> /tmp/save.log
echo "`date` : Fin de la compression de l'archive" >> /tmp/save.log
# envois ftp
cd /tmp
i=1
echo "envois"
echo "`date` : envoi ftp essai n°$i" >> /tmp/save.log
wput --reupload --dont-continue -B "$nom_archive.tar.gz" "ftp://$site" >> /tmp.save.log 2>> /tmp/save.log
i=`expr $i + 1`
while [ `ls -l "$nom_archive.tar.gz" | awk '{ print $5 }'` -ne `bash /home/seb/.script/ftp_get_size.sh "$site$nom_archive.tar.gz"` -a $i -le 3 ]
do
echo "`date` : envoi ftp essai n°$i" >> /tmp/save.log
wput --reupload --dont-continue -B "$nom_archive.tar.gz" "ftp://$site" >> /tmp.save.log 2>> /tmp/save.log
i=`expr $i + 1`
done
if [ $i -le 3 ]
then
echo "`date` : Envoi de l'archive terminée" >> /tmp/save.log
echo "ok" > /tmp/ok_$nom_archive
else
echo "`date` : Envoi de l'archive a échoué" >> /tmp/save.log
echo "" > "/home/seb/Bureau/`date` - save echoue"
fi
# suppression des fichiers temporaires
rm /tmp/save_path.tmp
rm /tmp/save_find.tmp
rm /tmp/save_exclude.tmp
rm /tmp/save_include.tmp
Dernière modification par sebk (Le 26/06/2008, à 17:55)
Iceberg Project : www.iceberg-linux.net
Hors ligne
#4 Le 30/06/2008, à 22:26
- sebk
Re : bug entre tar et xargs [résolus]
Si il y en a qui trouve mon code abscon (le shell script il est vrai est puissant mais pas très lisible) voici comment reproduire le bug :
Créer un fichier "toto.txt"
Créer un fichier "to\ \ to.txt" (deux espaces)
Créer un fichier "test.txt" qui contiendra le mon des deux fichiers (un par ligne)
Puis effectuer un : cat test.txt | xargs tar -cf archive.txt
Le deuxième fichier est en erreure
Iceberg Project : www.iceberg-linux.net
Hors ligne
#5 Le 08/07/2008, à 18:06
- sebk
Hors ligne
#6 Le 08/07/2008, à 20:11
- Totor
Re : bug entre tar et xargs [résolus]
je vais essayer de passer du temps sur ton pb demain sur mon temps de travail (si la solution n'a pas été trouvé d'ici là).
j'ai juste une petite question : pourquoi lances-tu toutes tes commandes via bash alors que ton script inclu : "#!/bin/bash" ? (je ne sais plus comment s'appelle cette ligne !)
-- Lucid Lynx --
Hors ligne
#7 Le 08/07/2008, à 20:21
- sebk
Re : bug entre tar et xargs [résolus]
le shebang je crois (je ne suis plus sûr de l'ortograf)
en fait je n'ai appris qu'il y a deux jours qu'on pouvais lancer un shell directement sans commande bash (et même supprimer le ".sh" pas beau) en cherchant à intégrer un script dans le système proprement
Iceberg Project : www.iceberg-linux.net
Hors ligne
#8 Le 09/07/2008, à 08:49
- Totor
Re : bug entre tar et xargs [résolus]
remplace ta ligne :
sudo -u $usersb cat /tmp/save_fichiers.log | xargs tar -rf /tmp/$nom_archive.tar 2> /tmp/save_tar.log
par :
sudo -u $usersb cat /tmp/save_fichiers.log | xargs -i{} tar -rf /tmp/$nom_archive.tar "{}" 2> /tmp/save_tar.log
le -i de xargs te permet de spécifier la chaine de caractère remplaçant tes arguments.
J'espère avoir répondu à ta question !
EDIT :
tu aurais pu utiliser l'option -exec de la commande find.
find <conditions de sélection> -exec tar rf /tmp/$nom_archive.tar "{}" \;
ce qui reviens exactement au même
Dernière modification par Totor (Le 09/07/2008, à 09:38)
-- Lucid Lynx --
Hors ligne
#9 Le 09/07/2008, à 22:15
- sebk
Re : bug entre tar et xargs [résolus]
Merci pour ta réponse
Je viens de tester ta solution et j'ai dut planter le traitement au bout de deux heures...
Tes solutions comportent le même problème que la première version de mon programme, à savoir que dans les deux cas, au lieu de faire un "tar -rf fichier1 fichier2 fichier3...", il fait :
tar -rf fichier1
tar -rf fichier2
...
a prioris ces solutions semblent revenir au même sauf au niveau performances :
- dans la solution 1 le tar ne prend pas la peine d'analyser l'archive à chaque fichier ==> une archive de 4Go se fait en une heure sur mon poste
- dans la solution 2 chaque tar analyse l'archive à chaque fichier et au bout de deux heures il en est à 1Go et prend de plus en plus de temps au fure et à mesure que l'archive grossit
En tout cas je retiends le xargs -i : ça peut être très util dans certains cas
Iceberg Project : www.iceberg-linux.net
Hors ligne
#10 Le 09/07/2008, à 22:55
- Totor
Re : bug entre tar et xargs [résolus]
Pour avoir l'ensemble des fichiers sur une seule ligne, essaie ceci (j'ai pas testé mais au pire,c'est une piste) :
sudo -u $usersb cat /tmp/save_fichiers.log | sed 's/ /\\ /g'|xargs echo tar rf /tmp/$nom_archive.tar|bash
Dernière modification par Totor (Le 09/07/2008, à 22:56)
-- Lucid Lynx --
Hors ligne
#11 Le 10/07/2008, à 20:11
- sebk
Re : bug entre tar et xargs [résolus]
Merci pour ton idée ! (j'aurais jamais pensé au pipe bash tout seul)
Après quelques essais voici la commade finale qui marche dans tous les cas :
cat /tmp/save_fichiers.log | sed "s/'/\\\\'/g" | sed "s/ /\\\\ /g" | sed "s/\"/\\\\\"/g" | xargs echo tar --ignore-failed-read -rf toto.tar | bash
Je m'empresse de mettre un joli résolus sur mon article
Iceberg Project : www.iceberg-linux.net
Hors ligne
#12 Le 10/07/2008, à 20:17
- Totor
Re : bug entre tar et xargs [résolus]
note : pour "alleger" tes sed, tu peux les remplacer par :
sed "s/'/\\\\'/g;s/ /\\\\ /g;s/\"/\\\\\"/g"
Dernière modification par Totor (Le 10/07/2008, à 20:18)
-- Lucid Lynx --
Hors ligne
#13 Le 10/07/2008, à 22:45
- sebk
Re : bug entre tar et xargs [résolus]
c'est bon à savoir
Encore merci
Iceberg Project : www.iceberg-linux.net
Hors ligne