Voici un scripts bash que j'ai developpé depuis un an petit à petit. Plus que de réellement vous servir quotidiennement, je pense que ce script pourra aider des personnes sur l'utilisation de certaines commande.
J'aimerais surtout avoir votre avis sur l'organisation global du script en général et aussi sur la gestion des erreurs qui est quasi-inexistante.
Code : Tout sélectionner
#!/bin/bash
# initie le 5/14
#
# conditions initiales pour le bon fonctionnement du script:
# -sdX -> ddi source
# -sdY -> dde destinataire
# -partition DOCUMENTS (inclu dans sdX) est deja montee
# -partition SAUVEGARDES (inclu dans sdY) n'est pas encore montee
# -les programmes wmctrl et countdown sont deja installes
# -on considere que les clefs usb n'ont qu'une partition chacune
#
# methode:
# -citer les sources
# -pres des fonctionnalitees du script
# -horodater les modifs avec description
# -erreur > fichier
# -...
#
# fonctionnalitees:
# -eteint la machine à la fin de la sauvegarde
# -sauvegarde part docs + sys + 1ere part de clefs clefs_usb
# -grace à renice, ne prend pas trop de ressource
# -plusieurs clef usb peuvent etre connectees a la fois
pause()
{
read -r -p "$*"
}
#function for handling errors:
error_exit()
{
local parent_lineno message code
message="$1"
if [ -n "$2" ]; then
code="$2"
else
code="1"
fi
if [ -n "$3" ]; then
parent_lineno="$3"
else
parent_lineno="?"
fi
if [ -n "$message" ]; then
echo "Error on or near line ${parent_lineno} : ${message}; exiting with status ${code}"
else
echo "Error on or near line ${parent_lineno}; exiting with status ${code}"
fi
pause
exit "${code}"
}
clean_up()
{
local code
if [ -n "$1" ]; then
code="$1"
else
code="0"
fi
if [ -n "$home" ] && [ -d "$dir_tmp" ]; then
rm -R "$dir_tmp"
fi
exit "$code"
}
#MBR:Master Boot Record
save_MBR()
{
check_mount "$mount_point_dest" "sauvegarde des mbr avortee : le dd de destination n'est pas connecte !"
check_root "sauvegarder les mbr"
if [ "$ismount" -eq "1" ] && [ "$isroot" -eq "1" ]; then
echo "sauvegardes des MBR des dd contenant les partions DOCUMENTS & SAUVEGARDES"
local ddi=${mount_point_docs:0:8}
local dde=${mount_point_dest:0:8}
rm -Rf "$dest_sauv"/mbr/
rm -Rf "$dest_sauv"/table_des_partitions/
check_dir "$dest_sauv"/mbr/
check_dir "$dest_sauv"/table_des_partitions/
for ddx in $ddi $dde
do
echo -e "coucou !\n"
local name=""
name="$(ls -l /dev/disk/by-id/ | grep -v part | grep "${ddx:5}" | awk '{print $9}' | head -1)_$date"
sfdisk -d "$ddx" > "$dest_sauv"/table_des_partitions/"${name}".dmp > /dev/null 2>&1
dd if="$ddx" of="$dest_sauv"/mbr/"${name}" bs=512 count=1 > /dev/null 2>&1
done
tar cP "$dest_sauv/mbr/" "$dest_sauv/table_des_partitions/" | gzip > "$dest_sauv/mbr_$date.tar.gzip"
su "$user" -c "gpg -r $user -e -a $dest_sauv/mbr_$date.tar.gzip"
rm "$dest_sauv/mbr_$date.tar.gzip"
# echo -e "From: $user\nTo: $user\nSubject: sauvegarde des mbr et cie du $date par $user" > "$dest_sauv/mbr_$date.tar.gzip.asc"
sed -i "1iSubject: sauvegarde des mbr et cie" "$dest_sauv/mbr_$date.tar.gzip.asc"
curl --url "smtps://smtp.belzebuth.ass:666" --ssl-reqd --mail-from "groderch@laposte.net" --mail-rcpt "groderch@laposte.net" --upload-file "$dest_sauv/mbr_$date.tar.gzip.asc" --user "groderch@laposte.net:ILoveSatan"
fi
}
#attention!!! fonction recursive!
mount_part()
{
# if [ ! "$(mount | grep $3)" ]
if mount | grep -q "$3"; then
echo "remontage de : $3"
umount_part "$1" "$3"
mount_part "$1" "$2" "$3"
else
echo "creation du dossier qui servira a monter la partition $1 puis montage de cette derniere"
if [ ! -d "$2" ]; then
mkdir "$2" || error_exit "Cannot create directory! Aborting" "$?"
fi
mount "$3" "$2" || error_exit "Cannot mount filesystem! Aborting" 32
fi
#sudo mount -t $4 $3 $2 || error_exit "Cannot mount filesystem! Aborting" 32
}
umount_part()
{
echo "demontage de la partition $1 puis suppression du dossier qui servit a monter cette derniere"
# umount -t $(mount | grep "$2" | awk '{print $5}') $2 || error_exit "Cannot umount filesystem! Aborting" $?
umount "$2" || error_exit "Cannot umount filesystem! Aborting" $?
if [ -d "$2" ]; then
rmdir "$2"
fi
}
sudo_rm()
{
su "$user" -c "/usr/bin/wmctrl -a Konsole"
echo -e "\033[1;31mLe dossier : \"$1\" sera supprime dans 15 secondes!\033[0m"
countdown.sh 15
rm -R "$1"
}
save_DOCUMENTS()
{
local delta dir tmp today file_tmp
let "delta=60*60*24*14"
today="$date"
file_tmp="$dir_tmp/list_of_dir.$$.$RANDOM"
check_dir "$destinataire"/docs_supprimes/"$today"/
check_dir "$destinataire"/logs/
check_dir "$dir_tmp"
echo "sauvegarde du contenu de la partition DOCUMENTS"
rsync -hau --delete --backup --backup-dir="$destinataire"/docs_supprimes/"$today"/ --stats --exclude=**/lost+found*/ --exclude=**/*Trash*/ --exclude=**/*trash*/ "$source/" "$destinataire/documents_perso/" > "$destinataire/logs/documents_perso_$today" || error_exit "Cannot use rsync! Aborting"
# sudo rsync -hau --progress --delete --backup --backup-dir=$destinataire/docs_supprimes/$today/ --stats --exclude=**/lost+found*/ --exclude=**/*Trash*/ --exclude=**/*trash*/ $source/ $destinataire/documents_perso/ || error_exit "Cannot use rsync! Aborting"
ls "$destinataire/docs_supprimes/" > "$file_tmp" || error_exit "Cannot use ls! Aborting"
if [ -s "$file_tmp" ]; then
cd "$destinataire/docs_supprimes/" || error_exit "Cannot use cd ! Aborting" "$?"
while read -r dir
do
if [ -n "${dir%%_*}" ]; then
let "tmp=$(date +%s)-${dir%%_*}" || error_exit "Cannot use let! Aborting"
else
let "tmp=$delta+1" || error_exit "Cannot use let! Aborting"
fi
if [ "$tmp" -gt "$delta" ]; then
sudo_rm "$dir"
fi
done < "$file_tmp"
fi
rm "$file_tmp"
# tree -Cqav "$source/" > "$destinataire/documents_perso/tree.txt"
}
save_sys_win()
{
check_dir "$destinataire/systemes/"
check_dir "$destinataire/logs/"
mount_part "WINDOWS" "/mnt/WINDOWS/" "$mount_point_win"
echo "sauvegarde du systeme windows actuel"
rsync -hau --delete --stats /mnt/WINDOWS/ "$destinataire/systemes/win" > "$destinataire/logs/systeme_win_${date}" || error_exit "Cannot use rsync! Aborting"
# tree -Cqav "/mnt/WINDOWS/" > "$destinataire/systemes/win/tree.txt"
umount_part "WINDOWS" "/mnt/WINDOWS/"
}
save_sys_lin()
{
check_dir "$destinataire/systemes/lin/"
check_dir "$destinataire/logs/"
echo "sauvegarde du systeme linux actuel"
rsync -auHX --delete --stats --numeric-ids --exclude=/media --exclude="/run/media/$user" --exclude=/tmp --exclude=/dev --exclude=/proc --exclude=/sys --exclude=/mnt --exclude=**/lost+found*/ --exclude=**/*Trash*/ --exclude=**/*trash*/ / "$destinataire/systemes/lin" >> "$destinataire/logs/systeme_lin_${date}"
# tree -Cqav "/" > "$destinataire/systemes/lin/tree.txt"
blkid > "$destinataire/logs/partitionnement_ddi_\(sudo_blkid\).txt" || error_exit "Cannot use rsync! Aborting"
fdisk -l > "$destinataire/logs/sudo_fdisk_-l.txt" || error_exit "Cannot use rsync! Aborting"
}
save_usb_key()
{
check_root "save usb and mmc keys"
if [ "$isroot" -eq "1" ]; then
local file_tmp="$dir_tmp/mount_point_key.$$.$RANDOM"
local dir_key_source="$HOME/key"
local dir_key_dest=""
local id_key=""
local t=""
check_dir "$dir_tmp"
for device in "usb" "mmc"
do
ls /dev/disk/by-id/*"$device"* > /dev/null 2>&1
if [ "$?" -eq "0" ]
then
ls /dev/disk/by-id/*"$device"* | grep part1 | grep -v TOSHIBA_External_USB_3.0 > "$file_tmp"
if [ -s "$file_tmp" ]
then
while read -r mount_point_key
do
id_key=${mount_point_key##*/}
dir_key_dest="$dest_sauv/clefs_usb/${id_key}"
t=$(ls -l /dev/disk/by-id/ | grep "$device" | grep part1)
t="/dev/${t##*/}"
check_dir "$dir_key_dest"
mount_part "de la clef $device" "$dir_key_source/" "$t"
echo "sauvegarde du contenu de la partition $t de la clef $device"
rsync -hau --delete-after --exclude=**/lost+found*/ --exclude=**/*Trash*/ --exclude=**/*trash*/ --exclude=**/musiques --exclude=**/videos --exclude=**/_ "$dir_key_source/" "$dir_key_dest" > "$dir_key_dest/log_${date}"
tree -Cqav "$dir_key_source/" > "$dir_key_dest/tree.txt"
umount_part "de la clef $device" "$dir_key_source/"
done < "$file_tmp"
rm "$file_tmp"
fi
else
echo "aucun peripherique $device n'est connecte!"
fi
done
fi
}
save_speedy()
{
local file_list="$dest_sauv/list.txt"
local output="$dest_sauv/save_speedy-${date}.tar.gzip"
tar cP --atime-preserve -T "$file_list" | gzip > "$output"
su "$user" -c "gpg -r $user -e -a $output"
rm "$output"
}
shutdown()
{
check_root "eteindre l'ordi"
if [ "$isroot" -eq "1" ]; then
local mes="extinction de l'ordinateur dans 30 secondes!"
local tmp=""
tmp="$(wmctrl -l | grep -im 1 "terminal")"
tmp="${tmp:0:10}"
su "$user" -c "/usr/bin/wmctrl -ia $tmp"
su "$user" -c "/usr/bin/notify-send -i /usr/share/icons/oxygen/32x32/actions/system-shutdown.png backup.sh \"$mes\""
echo -e "\e[1;31m$mes\e[0m"
su "$user" -c "/usr/bin/espeak -v fr \"$mes\""
read -r -n 1 -t 30 test
if [ -z "$test" ]
then
countdown.sh "10"
shutdown -h now
fi
fi
}
restore_systeme()
{
local answer=""
check_dir "$destinataire/logs/"
echo "restauration du systeme sauvegarde sur $1"
echo "Voulez-vous supprimer le contenu de $1? [y/n]"
read -r answer
if [ "$answer" = "Y" -o "$answer" = "y" ];
then
rm -R "${1:?}/"
rsync -ha --stats --numeric-ids "$destinataire/systemes/" "$1" > "$destinataire/logs/restore_system_${date}.txt"
cd "$1" || error_exit "Cannot use cd ! Aborting" "$?"
mkdir mnt tmp proc media dev sys
fi
}
show_help()
{
echo "aide:"
echo " -k sauvegarde du contenu des clefs usb avec suppressions des fichiers de destinations qui ne sont pas a la source"
echo " -s sauvegarde des documents precieux puis compression et chiffrement de ces derniers"
echo " -m sauvegarde des MBR uniquement"
echo " -d sauvegarde des documents uniquement"
echo " -l sauvegarde du systeme linux uniquement"
echo " -w sauvegarde du systeme windows uniquement"
echo " -x execution de shutdown -ah now"
# echo " -r /dev/sdXY restauration du systeme"
echo "sinon, tout en même temps dans l'ordre sauf les parametres -s, -k"
echo " -h cette aide"
}
load_conf()
{
check_root "load conf"
if [ "$isroot" -eq "1" ]; then
type tree > /dev/null 2>&1 || echo "veuillez installer tree"
type wmctrl > /dev/null 2>&1 || echo "veuillez installer wmctrl"
type espeak > /dev/null 2>&1 || echo "veuillez installer espeak"
type rsync > /dev/null 2>&1 || echo "veuillez installer rsync"
if [ ! -e "/etc/backup.conf" ]
then
echo "Voici les partitions disponibles :"
blkid -o list
echo -e -n "Entrer le nom d'utilisateur :\n\t->"
read -r user
echo -e -n "Entrer l'uuid de la partition contenant les documents :\n\t->"
read -r uuid_docs
echo -e -n "Entrer l'uuid de la partition contenant le systeme windows:\n\t->"
read -r uuid_win
echo -e -n "Entrer l'uuid de la partition où tout sera sauvegarde :\n\t->"
read -r uuid_dest
# touch "/etc/backup.conf" || error_exit "Cannot create file! Aborting"
echo "$user $uuid_docs $uuid_win $uuid_dest" > "/etc/backup.conf" || error_exit "Cannot write in file! Aborting"
else
read -r user uuid_docs uuid_win uuid_dest source < "/etc/backup.conf" || error_exit "Cannot read in file! Aborting"
fi
else
exit "0"
fi
}
restore()
{
part_name=$(blkid "$OPTARG")
part_name=${part_name##*LABEL=\"}
part_name=${part_name%%\"*}
if [[ $OPTARG != /dev/sd* ]]; then
echo "l'argument doit etre du type \"/dev/sdXY\", avec X et Y des lettres de l'alphabet!"
clean_up 0
fi
echo "-- restauration du systeme sur la partition $part_name --"
mount_part "SAUVEGARDES" "$destinataire/" "$mount_point_dest"
mount_part "$part_name" "/media/RESTORE/" "$OPTARG"
restore_systeme "/media/RESTORE"
umount_part "$part_name" "/media/RESTORE/"
umount_part "SAUVEGARDES" "$destinataire/"
unset part_name
}
check_dir()
{
if [ ! -d "$1" ]; then
mkdir -p "$1" || error_exit "Cannot create directory! Aborting"
fi
}
check_space()
{
df | grep "$1" | awk '{ print $1; }'
}
check_root()
{
isroot="0"
if [ "$(id -u)" -eq 0 ]; then
let "isroot=1"
else
echo "ERROR: Must be run as root for $1. Script terminating."
fi
}
#if device recipient is plug
check_mount()
{
ismount="0"
if [ -n "$1" ]; then
let "ismount=1"
else
echo "$2"
let "fait=0"
fi
}
manage_saves()
{
check_mount "$mount_point_dest" "sauvegarde des systemes et/ou documents avortee : le dd de destination n'est pas connecte !"
check_root "save documents"
if [ "$ismount" -eq "1" ] && [ "$isroot" -eq "1" ]; then
mount_part "SAUVEGARDES" "$destinataire/" "$mount_point_dest"
countdown.sh 5
case "$1" in
DOCS)
save_DOCUMENTS
;;
SYS_LIN)
save_sys_lin
;;
SYS_WIN)
save_sys_win
;;
ALL)
save_DOCUMENTS
save_sys_win
save_sys_lin
;;
esac;
umount_part "SAUVEGARDES" "$destinataire/"
fi
}
#trap 'error_exit ${LINENO}' 1 15 ERR
trap clean_up SIGHUP SIGINT SIGTERM
user=""
date=$(date +%s_%kh%M_le_%a_%d_%b_%Y)
#file_errors="$destinataire/logs/erreurs.txt"
mount_point_dest=""
mount_point_docs=""
uuid_docs=""
uuid_win=""
uuid_dest=""
fait="1"
load_conf
home="/home/$user"
# destinataire="/mnt/SAUVEGARDES"
destinataire="/run/media/$user/SAUVEGARDES"
dir_tmp="$home/tmp/"
mount_point_dest=$(blkid -U $uuid_dest)
mount_point_docs=$(blkid -U $uuid_docs)
mount_point_win=$(blkid -U $uuid_win)
source=$(mount | grep "$mount_point_docs" | awk '{print $3 }')
dest_sauv="$source/Documents/backup"
check_dir "$dest_sauv"
# On donne une priorité faible au processus pour ne pas dégrader les performances des autres applications
renice +19 $$
# while getopts "lwdmhxr:kKs" opt
while getopts "lwdmhxkKs" opt
do
case $opt in
l)
echo "-- sauvegarde du systeme linux uniquement --"
manage_saves "SYS_LIN"
;;
w)
echo "-- sauvegarde du systeme windows uniquement --"
manage_saves "SYS_WIN"
;;
d)
echo "-- sauvegarde des documents uniquement --"
manage_saves "DOCS"
;;
m)
echo "-- sauvegarde des MBR uniquement --"
save_MBR
;;
h)
show_help
clean_up 0
;;
x)
shutdown
;;
# r)
# restore
# ;;
k)
echo "-- sauvegarde des clefs usb et mmc uniquement --"
save_usb_key
;;
s)
echo "-- sauvegarde rapide --"
save_speedy
;;
\?)
echo "invalid option: -$OPTARG"
show_help
clean_up 0
;;
esac
done
if [ "$#" -eq "0" ]; then
echo "-- sauvegarde generale --"
save_usb_key "--delete"
save_MBR
manage_saves "ALL"
if [ $fait -eq "1" ]; then
shutdown
fi
fi
countdown.sh "3"
clean_up "1"
# le programme countdown.sh:
# #!/bin/bash
#
# beginning=$(date +%s)
# diff="0"
# rest="$1"
# tmp="0"
# now="0"
#
# echo -n "$1"
# while [ "$diff" -lt "$1" ]
# do
# let "now=$(date +%s)"
# let "diff=now-beginning-1"
# let "tmp=$1-diff"
# if [ "$tmp" -lt "$rest" ]
# then
# let "rest=$1-diff"
# echo -n ", $rest"
# fi
# done
#
# echo ""