Problème script de synchro

Je ne peux pas tester le script à la main car c’est une action déclenchée par Udev.

@Totor: Y a t’il une raison pour utiliser cdm1 > >(cmd2) plutôt que cmd1 | cmd2 où c’est juste par goût ?

Je reposte le script complet:

[code]#! /bin/bash

######################################################################################

Script de gestion de connexion et sauvegarde du /home de la clef sur le poste fixe

######################################################################################

#------------------------------------------------------------------------------------#

Fonction

#------------------------------------------------------------------------------------#

#afficheTaille () {

taille=$(sed ‘/./! s/^.*$/&.00/’ <<< $1)

i=1

while [[ ${#taille} -ge 7 ]]; do

taille=$(bc <<< “scale=2;$taille/1024”)

((i+=1))

done

case $i in

1) taille+=" octets" ;;

2) taille+=" Ko" ;;

3) taille+=" Mo" ;;

4) taille+=" Go" ;;

esac

echo $taille

#}

#-------------------------------------------------------------------------------------#

Déclaration des variables

#-------------------------------------------------------------------------------------#

Paramètres d’identification de la clef

DEVTYPE="usb"
ID_SERIAL_SHORT="A500000000026452"
KEY_SYNC=/dev/LiveUSB2
USERNAME=“leseb” # Indispensable pour l’affichage des fenêtres Zenity

Répertoire source, destination, de montage de LiveUSB2, du montage du volume crypté, de backup du .img

SRC_DIR=/home/leseb/MOUNT/
DEST_DIR=/home/leseb/udevsync/
MONT_POINT=/home/leseb/MOUNT/
CRYPT_MOUNT=/home/leseb/CRYPT/
CONTENEUR=/home/leseb/MOUNT/luks-home.img
BKP_CONT=/home/leseb/Backup_IMG/

Fichiers de log horodatés

BKP_DATE=date +"%Y-%m-%d_%H-%M"
LOG_FILE=/tmp/Logs_Sync/sdBackup_${BKP_DATE}.log
BKP_LOG_FILE=$DEST_DIR/Logs_Sync/sdBackup_${BKP_DATE}.log
RSYNC_ERR=/tmp/rsync.err

#------------------------------------------------------------------------------------#

Algo

#------------------------------------------------------------------------------------#

Initialisation du fichier de log

echo “Backup du $BKP_DATE” >> $LOG_FILE
echo "Début à date +'%H:%M:%S'" >> $LOG_FILE

Action à l’insertion de la clef

if [ “$ID_FS_TYPE” = “ext2” ] ; then # Variable de UDev pour l’insertion de clef

# Montage de la partition contenant le volume crypté
mount $KEY_SYNC $MONT_POINT

# Demande de synchronisation
su - ${USERNAME} -c "DISPLAY=:0.0 zenity --question  --title='Bienvenue' --text='Clef montée. \nVoulez-vous synchroniser le <b>/home</b> de la clef ?'"

if [ "$?" = 0 ]; then # Si on clique sur "Valider"

	if [ -f $CONTENEUR ] ; then # vérifie si le volume crypté existe

		# Cherche un loop libre
		#loop=$(losetup -f)
		#losetup $loop $MONT_POINT

		# Ouverture du conteneur et saisie de mot de passe, choix de saisir ou d'annuler l'opération avec le if

		#if MDP=$(${USERNAME} -c "DISPLAY=:0.0 zenity --entry \ 
		#			--title='Ouverture du conteneur chiffré' \
		#			--text='Entrez le mot de passe pour ouvrir le conteneur chiffré' \
		#			--hide-text')")
		#			then echo $?
		#else 	su - ${USERNAME} -c "DISPLAY=:0.0 zenity --info --title='Champ vide' --text='Opération abandonnée'"
		#fi

		#cryptsetup luksOpen $loop LUKS # Esseyé de renvoyer MDP dans cryptsetup MAIS COMMENT ?

		# Monter
		#mount -o loop /dev/mapper/LUKS $CRYPT_MOUNT
		
		# Barre de progression
		affiche()
		{
		   fichier=""
		   numFichier=0
		   nbFile=
		   while read uneLigne
		   do
		     [ "${uneLigne}" ]  && {
			[[ "${uneLigne}" =~ [[:digit:]\.]+[A-Z]\ *[[:digit:]]+% ]] &&  {
			   infos=( ${uneLigne} )
			  
			   transfere=${infos[0]}
			   evolution=${infos[1]%\%}
			   indice=2
			  
			   [[ "${transfere}"  = *100% ]] &&
			   {
			       transfere=${transfere%100%}
			       evolution=100
			       indice=1
			   }
			  
			   debit=${infos[${indice}]}
			   tps=${infos[((${indice}+1))]}
			  
			   [ ! "${nbFile}" ] && [[ "${uneLigne}" = *to-check* ]] && {
			      indice=${#infos[@]}
			      ((indice--))
			      nbFile="${infos[${indice}]}"
		      nbFile=${nbFile%)}
			      nbFile=${nbFile#*/}
			   }
			  
			   echo "#Fichier : ${fichier}$( [ "${nbFile}" ] && echo " (${numFichier}/${nbFile})")\nTransféré : ${transfere}\nDébit : ${debit}\nTemps restant : ${tps}"
			   echo ${evolution}
			  
			} || {
			    fichier="${uneLigne}"
			    echo "#Fichier : ${fichier}$..."
			    echo 0
			    ((numFichier++))
			 }
		      }
		  done  > >(su - ${USERNAME} -c "DISPLAY=:0.0 zenity --progress --width=580 --title='Synchronisation' --text='Initialisation de la sauvegarde...' --auto-close")
		}
		 #Synchro
		rsync -rpvh --progress $SRC_DIR "$DEST_DIR" > >(awk ' BEGIN { RS="\n|\r" } { print; fflush() }' > >(affiche)) 

		#    echo "0" > nb
		#    DEBUT=$(date +%s)

		 #   rsync -av --delete --ignore-errors --force --progress \
		 #   $SRC_DIR/ $DEST_DIR/ 2>>$RSYNC_ERR | sed '
		 #   /to-check=/! {
		 #     /^sending/  {d;q;}
		 #     /\/$/       {d;q;}
		 #     /^sent/     {s/^.*$/echo "&" \>\/tmp\/rapport\.txt/e;d;q;};
		 #     /^total/    {s/^.*$/echo "&" \>\>\/tmp\/rapport\.txt/e;d;q;};
		 #     /^.\{43\}/  {s/\(^.\{20\}\).*\(.\{20\}$\)/echo \$\(\(\$\(cat nb\) + 1\)\) \> nb; echo "\1\[...\]\2" \>\/tmp\/svgrd_sed\.txt/e;d;q;};
		 #     /^.\{43\}/! {s/^.*$/echo \$\(\(\$\(cat nb\) + 1\)\) \> nb; echo "&" \>\/tmp\/svgrd_sed\.txt/e;d;q;};
		 #   }
		 #   /to-check=/ {
		 #     s/.*=\(.*\)\/\(.*\))/echo "#`echo "scale=2;\(\2-\1\)\*100\/\2" | bc | cut -d\. -f1`% (\$\(\(\2 - \1\)\) fichiers sur \2\) > \$\(cat \/tmp\/svgrd_sed\.txt\)"\; echo "scale=2;\(\2-\1\)\*100\/\2" | bc/e
		 #   }
		 #   ' | su - ${USERNAME} -c "DISPLAY=:0.0 zenity --progress --width=580 --title='Synchronisation' --text='Initialisation de la sauvegarde...' --percentage=0 auto-close"

		FIN=$(date +%s)
		TEMPS=$(($FIN-$DEBUT))
		TP_HEU=$(sed 's/^.$/0&/' <<< $(($TEMPS/3600)))
		TP_TMP=$(($TEMPS%3600))
		TP_MIN=$(sed 's/^.$/0&/' <<< $(($TP_TMP/60)))
		TP_SEC=$(sed 's/^.$/0&/' <<< $(($TP_TMP%60)))
		TP=$(echo "$TP_HEU:$TP_MIN:$TP_SEC")
	
		# Vérifie la sortie de rsync
		ERR=$(cat $RSYNC_ERR)
		if [[ ${#ERR} -ne 0 ]]; then
			su - ${USERNAME} -c "DISPLAY=:0.0 zenity --error --title='Erreur de copie' --text='Problème lors de la sauvegarde du répertoire <b>$MOUNT_POINT</b>.\n\n<b><span color='red'>$ERR</span></b>.'"
			rm $RSYNC_ERR
		else
			NB_FICH=$(cat nb)
			ENVOI=$(afficheTaille $(cat /tmp/rapport.txt | grep sent | cut -d' ' -f2))
			RECU=$(afficheTaille $(cat /tmp/rapport.txt | grep sent | cut -d' ' -f6))
			VITESS=$(afficheTaille $(cat /tmp/rapport.txt | grep sent | cut -d' ' -f9))
			su - ${USERNAME} -c "DISPLAY=:0.0 zenity --info --title='Terminé' --text='Sauvegarde du répertoire\n<b>$MONT_POINT</b> effectuée avec succès.\n$NB_FICH fichiers synchronisés\nTemps:\t$TP\nTransfert:\t$VITESS/sec'"
			rm nb
		fi    

		# Copie du log sur le répertoire de synchro
		cp -f $LOG_FILE $BKP_LOG_FILE

		# Précaution de backup du conteneur crypté
		cp $CONTENEUR $BKP_CONT 
	else
		su - ${USERNAME} -c "DISPLAY=:0.0 zenity --error \
		--title='Erreur' \
		--text='Aucun volume crypté trouvé !'"

	fi

fi

fi

if [ “$ACTION” = “remove” ] ; then # Variable de UDev

# Démonter le volume crypté
#umount $CRYPT_MOUNT

# Fermer le volume crypté
#cryptsetup luksClose LUKS

# Libérer le loop
#losetup -d $loop

# Démontage de la clef
umount -f $KEY_SYNC >> $LOG_FILE
echo "Clef "$ID_MODEL" démontée ("$ACTION")" >> $LOG_FILE

fi

#------------------------------------------------------------------------------------#

EOF

#------------------------------------------------------------------------------------#[/code]

ENVOI=$(afficheTaille $(cat /tmp/rapport.txt | grep sent | cut -d' ' -f2)) RECU=$(afficheTaille $(cat /tmp/rapport.txt | grep sent | cut -d' ' -f6)) VITESS=$(afficheTaille $(cat /tmp/rapport.txt | grep sent | cut -d' ' -f9))
peut être remplacé par :

data=$(awk '/sent/{ print "("$2" "$6" "$9")"}') ENVOI=$(afficheTaille ${data[0]}) RECU=$(afficheTaille ${data[1]}) VITESS=$(afficheTaille ${data[2]})
Les avantages ?
[ul][li]on évite la mauvaise utilisation de cas[/li]
[li]on évite des pipe assez consommateurs[/li]
[li]on utilise qu’un seul programme[/li]
[li]on ne parse qu’une seul fois le rapport (même s’il est en cache)[/li][/ul]

Pour la barre de progression je ne connais pas zenity.

Dans le cas présent, c’est plus part habitude. Sinon, y’a une raison :
L’utilisation de pipe engendre la création de processus impliquant que les variables utilisées au sein de ces processus n’ont qu’une portée locale à ces processus. Alors que l’utilisation de la substitution de processus permet de modifier des variables (et de conserver ces modifications) qui ont été définies en dehors des commandes enchainées.

Pour le reste du script, je donnerai une réponse demain

EDIT : j’ai pas trop le temps de travailler sur le script aujourd’hui. Et ce soir, je suis de sortie
Par contre, quelque chose m’interpèle :
Pourquoi utiliser su pour afficher zenity ? Il n’y a pas d’intérêt à moins que tu ne planifies le script en crontab…
Est-ce le cas ?

Si c’est le cas, il est préférable de définir la variable DISPLAY avant d’appeler le script (où en tout débit de script)
L’utilisation de su devient alors inutile.

[quote=“MisterFreez”]

Oh làlà, y’a quelques trucs qui ne vont pas :

  • Il manque la source des données
  • la construction du tableau est complètement erronée

Mais toujours est-il que l’utilisation du fichier temporaire est inutile. Il suffit de lire le flux de données via read et de le décomposer.

Le script ne se lance pas en crontab mais grâce à Udev lors de la connexion de la clef USB.
Pour le code que tu as rajouté où dois-je le placer ?

[quote=“Totor”][quote=“MisterFreez”]

Oh làlà, y’a quelques trucs qui ne vont pas :

  • Il manque la source des données
  • la construction du tableau est complètement erronée

Mais toujours est-il que l’utilisation du fichier temporaire est inutile. Il suffit de lire le flux de données via read et de le décomposer.[/quote]
Pour la source c’est un oublie. Pour le tableau bien que je ne m’en suis jamais servis j’ai testé en faisant ça:

et ça marche.
ta construction

crée chez moi une variable “1,2,3”.

Je ne comprend donc pas.

c’est effectivement étrange que ça te crée une variable “1,2,3” :open_mouth:
Normalement, l’OFS de awk est un espace. Dans l’immédiat, voici des solutions :

data=( $(awk '/sent/ {print $2" "$6" "$9}' /tmp/rapport.txt) )

ou modifier l’OFS :

data=( $(awk '/sent/ {OFS=" ";print $2" "$6" "$9}' /tmp/rapport.txt) )

ou manipuler le résultat en bash :

data="$(awk '/sent/ {print $2,$6,$9}' /tmp/rapport.txt)"
data=( ${data//,/ } )

NOTE : Je n’ai pas oublié le script, j’ai juste peu de temps en ce moment

On s’est peut être mal compris. L’idée c’était de générer un tableau pour pouvoir initaliser 3 variables en une fois. Chez moi les tableau bash se font ainsi :

du coup je fais en sorte que awk me génère directement un tableau.

on s’est bien compris !
mais par awk, ça ne fonctionnera pas car l’interprétation des parenthèses ne s’effectuera pas car bash considère qu’elles font partie intégrante de la valeur retournée par awk.
Si l’on reprend la ligne :

la variable data aura pour valeur “( )”

Pour ceci :

je me demande si tu n’as pas fait quelque chose comme ceci ?

alors que moi :

les parenthèses sont à l’exterieur de awk. Dans awk, les virgules sont utilisés pour séparer les valeurs de paramètres passés à l’instruction print de awk. l’affichage s’effectuant sur une seule et même ligne en séparant chaque valeur par la valeur de la variable interne à awk “OFS” (=Output Field Separator)dont la valeur par défaut est la même valeur par défaut de l’autre variable interne “IFS” (Input Field Separator), c.a.d espace / tabulation)

J’ai refais quelque manip et cela fonctionne ! Juste quelques erreurs de ma part.
Merci à tous pour votre aide :smiley:

Fais-nous profiter du résultat final :wink:
Ensuite tu pourras marquer le topic comme résolu.

Nouvelle mouture avec :

  • ajout du rapport final
  • correction de l’affichage
  • ajout de la gestion d’un fichier de log

Je vous laisse gérer le montage du support de sauvegarde (ce n’est pas le plus difficile)…

#!/bin/bash
affiche()
{
	fichier=""
	nbFile=
	while read uneLigne
	do
	  [ "${uneLigne}" ]  && {
		  [[ "${uneLigne}" =~ [[:digit:]\.]+[A-Z]\ *[[:digit:]]+% ]] &&  {
			  infos=( ${uneLigne} )
			  
			  transfere=${infos[0]}
			  evolution=${infos[1]%\%}
			  indice=2
			  
			  [[ "${transfere}"  = *100% ]] && 
			  {
				   transfere=${transfere%100%}
				   evolution=100
				   indice=1
			  }
			  
			  debit=${infos[${indice}]}
			  tps=${infos[((${indice}+1))]}
			  
			  [[ "${uneLigne}" = *to-check* ]] && {
				  indice=$((${#infos[@]}-1))
				  nbFile="${infos[${indice}]}"
				  nbFile=${nbFile%)}
				  nbFile=${nbFile#*=}
				  ((indice--))
				  numFichier="${infos[${indice}]}"
				  numFichier=${numFichier#*#}
				  numFichier=${numFichier%,}
			  }
			  
			  echo "#Fichier : ${fichier}\nTransféré : ${transfere}\nDébit : ${debit}\nTemps restant : ${tps}$([ "${nbFile}" ] && echo "\n\nNb fich. transféré(s) : ${numFichier}\nNb fich. restant(s) : ${nbFile}")"
			  echo ${evolution}
			  
		  } || { 
			      {
				   [ -f "${uneLigne}" ] && { 
					     fichier="${uneLigne}"
						 echo "Fichier : ${fichier}"
				    }
				} ||  {					
			       [[ "${uneLigne}" = sent*received*/* ]] && {
					   infos=( ${uneLigne} )
					   echo 100
					   echo "#Fin du transfert : ${infos[1]} ${infos[2]} transférés\nDébit moyen : ${infos[6]}"
				   }
		        }
		   }
       }
	done  > >(zenity --progress --width=580 --title="svgrd - synchronisation" --text="Initialisation de la sauvegarde..." --percentage=0 --auto-kill)
}

rsync -rpvh --progress <SOURCE(S)> <DEST>|tee <FICHIER_LOG> > >(awk ' BEGIN { RS="\n|\r" } { print; fflush() }' > >(affiche))

Bein écoute ça m’a l’air mignon tout plein :slightly_smiling:
Peut-être prendre aussi stderr pour le tee, sinon je crois que ton log ne verra pas toutes les erreurs.

Bonjour,
Il y a t-il une raison précise pour utiliser zenity?
Si c’est juste pour la barre de progression, à mon avis dzen2 est moins lourd et a aussi tout ce qui faut pour ça, avec dbar et gdbar.