page header

maart 2011 Archieven

Zenity in de praktijk


Geplaatst door Martijn Brekhof op 2011-03-28 13:25:32 | Permanente link | Categorie: ATComputing, Tips and Tricks | Reacties: 0

In m'n vorige blog heb ik de tool zenity behandeld en hoe je hiermee in een script grafische interactie met een gebruiker kan bewerkstelligen.

Ik zal nu een script behandelen waarin ik zenity gebruik voor de grafische gebruikers interactie. Het script wordt gebruikt om laptops te backuppen naar een externe harddisk.

Het script ziet er als volgt uit:

 1  #!/bin/bash
 2  
 3  PATH=/bin:/usr/bin/
 4  LOGFILE=/var/log/backupserver.log
 5  BACKUPDIRS="/usr/local /home"
 6  
 7  function cleanup
 8  {
 9     rm ${TMPFILE}
10     if umount "${TMPDIR}" >> ${LOGFILE} 2>&1
11     then
12         rmdir "${TMPDIR}"
13     else
14         zenity --error --text='Could not unmount the backup device!'
15         exit 1
16     fi
17  }
18  
19  function cancel_backup
20  {
21     kill ${RSYNCPID}
22     wait ${RSYNCPID}
23     sleep 1
24     cleanup
25     echo "Backup cancelled at "`date` >> ${LOGFILE}
26     zenity --info --text='Backup cancelled.
27  You may now disconnect the backup device.'
28     exit 1
29  }
30  
31  TMPDIR=`mktemp -d /media/backupdisk.XXX` || exit 1
32  TMPFILE=`mktemp /tmp/backupdiskfifo.XXX` || exit 1
33  trap cancel_backup SIGINT SIGTERM SIGHUP
34  
35  if ! mount "/dev/$1" "${TMPDIR}"
37  then
38     echo "Error mounting /dev/$1 on ${TMPDIR}" >> ${LOGFILE}
39     exit 1
40  fi
41  
42  echo "Backup started at "`date` >> ${LOGFILE}
43  nice -n 20 rsync -v --delete -a --bwlimit=100024 ${BACKUPDIRS} \
44   "${TMPDIR}" > ${TMPFILE} &
45  RSYNCPID=$!
46  
47  zenity --list --title "Backup" --text='Backup in progress.
48  Do not disconnect the disk!' --column "Files" < ${TMPFILE}
49  
50  [ $? -eq 0 ] || cancel_backup
51  
52  wait ${RSYNCPID}
53  sleep 1
54  cleanup
55  echo "Backup finished at "`date` >> ${LOGFILE}
56  zenity --info --text='Backup finished.
57  You may now disconnect the backup device.'
58  exit 0

Op regel 5 wordt de variabele BACKUPDIRS gedefinieerd die een lijst met directories en files bevat (gescheiden door witruimte) die moeten worden gebackupt. Vervolgens definieer ik twee functies genaamd clean_up en cancel_backup. De eerste zal de backup-disk unmounten en tijdelijke bestanden en directories verwijderen. De tweede wordt aangeroepen als de backup-procedure wordt afgebroken. In deze twee functies zien we al het gebruik van zenity. In de functie clean_up wordt zenity gebruikt om bij problemen met het unmounten van de backup-disk de gebruiker te waarschuwen. Dit is nodig zodat de gebruiker eventueel het probleem zelf kan analyseren of hulp kan inschakelen. In de functie cancel_backup wordt zenity gebruikt om te melden dat de backup-procedure succesvol is afgebroken en dat het nu veilig is om de backup-disk fysiek te ontkoppelen.

Het script vereist dat je één argument meegeeft, namelijk de disk-partitie waarop de backup moet worden gemaakt. Let op, hierbij moet je niet het volledige pad opgeven maar het relatieve pad vanaf /dev. Dit is zo gedaan omdat ik dit script normaliter wil laten starten via udev. Hier zal ik in een volgend blog meer over vertellen. Stel dat de backup disk-partitie de device-file /dev/sdd1 heeft dan moet je het script als volgt runnen

./backupscript.sh sdd1

Op regels 31 en 32 wordt er een tijdelijke directory en een file aangemaakt met behulp van het commando mktemp. Dit commando heeft als voordeel dat het garandeert dat de gemaakte directory- of filenaam uniek is op het filesysteem. De tijdelijke directory zal worden gebruikt om de backup-disk te mounten en het tijdelijke bestand zal worden gebruikt om de uitvoer van het feitelijke backup-commando in op te slaan.

Vanaf regel 35 gaan we de kritieke fase in van het script. De disk zal worden gemount en de backup gestart. Stel nu dat tijdens deze fase het script wordt afgebroken, dan is het mogelijk dat de backup-disk gemount blijft en de tijdelijke directory en het tijdelijke bestand niet worden opgeruimd. Om dit zoveel mogelijk te voorkomen definiëren we een zogenaamd trap(regel 33) . Hiermee geven we aan dat de shell de functie cancel_backup moet uitvoeren wanneer het interrupt (SIGINT), hangup (SIGHUP), of terminate (SIGTERM) signaal wordt ontvangen.

Op regel 43 begint de eigenlijke backup. De uitvoer van het rsync-commando wordt weggeschreven in het tijdelijke bestand en het commando wordt in de achtergrond uitgevoerd. Vervolgens wordt zenity opgestart in de zogenaamde list-mode. We geven dan via de standaard invoer (<) de inhoud van het tijdelijke bestand aan zenity. Zenity zal dan de inhoud van het bestand in een venster tonen, ook wanneer er nieuwe regels worden toegevoegd aan het bestand. Zo kunnen we tijdens het maken van de backup de vorderingen zien. Het scherm van zenity zal twee knoppen bevatten: cancel en ok. Wanneer de gebruiker op cancel drukt zal zenity stoppen met exit-waarde 1 en de backup-procedure worden afgebroken. Als de gebruiker op ok drukt zal zenity stoppen maar de backup-procedure door blijven draaien. De gebruiker krijgt dan pas na het voltooien van de backup-procedure weer een melding via zenity dat de backup voltooid is (regel 56).