Comparing folders - autocopy script

Hey Guys,

first of all: I'm new to unix and im not very experienced.
I've bought a rapsberry pi and i want it to be the backup-machine for my SD-Cards while im travelling (attached ssd, card reader, a small touch-tft)

I managed to modify it a litte bit (its sending information bubbles to the desktop).

What this script is doing:

  1. It starts copying photos and videos as soon as i plug in a card reader (automatically)

My problem:
I want the script to do a check. To compare the old folder and the new folder and to check if everything has been transfered properly.
I don't even know where to start. I can't do it by myself.

I don't even know what the script should compare? Filesize? Number of files? Filesize seems a little risky, the sd-cards partition could be NTFS...AND the script should check the ,,FILE_MATCH=".*\" formats only.

Can anyone help?
I would appreciate it! :slight_smile:

Kind regards

#!/bin/bash
#
# sd-autocopy - Copies/Moves images automatically from inserted media
#
# Copyright (c) 2011 Lars Michelsen <lm@larsmichelsen.com>;
#
# License:
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

# But this in curly braces and detach the whole block to background
# for not blocking udev during copying.
{

# 2016/04/15, Cubbi: ignore blockdevice
if [ "$UDISKS_PARTITION_TABLE" -eq "1" ]; then exit 0; fi

USER=root #unter welchen Rechten die Dateien gespeichert werden -- SMB USER!
TARGET=/media/ssd/_upload #Zielverzeichnis eintragen
HANDLED_SERIALS=TS-RDF5_SD_Transcend_000000000039-0:0
MOUNT=/media/cardreader #Ordner vorher erstellen
FILE_MATCH=".*\.(jpg|cr2|jpeg|pdf|mkv|avi|mp4|3gp|mpg|mov|mpeg|wma|wmv|vob|mts)$" #hier die Dateiformate eintragen
TRANSFER=cp #cp f�r kopieren, mv f�r verschieben
TIMESTAMP=$(date +%Y%m%d%H%M%S) #timestamp f�r Unterordner

# END OF CONFIGURATION ########################################################

# DEBUG:
# To enable debugging without udev events uncomment the lines below
#ID_SERIAL=0x000006d4
#DEVNAME=/dev/mmcblk0p1

# Catch unset but needed vars - terminate script
if [ -z "$ID_SERIAL" ] || [ -z "$DEVNAME" ]; then
    exit 1
fi

if ! echo "$HANDLED_SERIALS" | grep $ID_SERIAL >/dev/null 2>&1; then
    logger -t sd-autocopy "Card not accepted!"
        exit 1
fi

logger -t sd-autocopy "Karte akzeptiert. Starte Kopiervorgang..."
sudo -u pi DISPLAY=:0.0 notify-send 'start'

sleep 10

if [ ! -d "$MOUNT" ]; then
    mkdir -p "$MOUNT"
fi

mount $DEVNAME "$MOUNT"

LINES=$(find "$MOUNT" -regextype posix-egrep -iregex "$FILE_MATCH" -printf "%TY-%Tm-%Td_%p\n")
DATES=$(echo "$LINES" | cut -d_ -f1 | uniq)

# First create the directories when missing
for DATE in $DATES; do
    echo $DATE
    mkdir -p "$TARGET/$TIMESTAMP/$DATE"
done

# Move the images
NUM=0
for LINE in $LINES; do
    DATE=${LINE%%_*}
    FILE=${LINE#*_}
    logger -t sd-autocopy "Kopiere $FILE"
    $TRANSFER "$FILE" "$TARGET/$TIMESTAMP/$DATE"
    NUM=$(($NUM+1))
done

umount $DEVNAME
umount "$MOUNT"

# Fix the permissions for all directories recursive where
# files have been copied/moved to
for DATE in $DATES; do
    chown -R $USER.$USER "$TARGET/$TIMESTAMP"
chmod -R 775 /media/ssd
done

logger -t sd-autocopy "Fertig! $NUM Dateien kopiert."
sudo -u pi DISPLAY=:0.0 notify-send 'fertig'

} &
exit 0

It would seem that after the line:

    $TRANSFER "$FILE" "$TARGET/$TIMESTAMP/$DATE"

you would want to run command something like:

    if ! cmp "$FILE" "$TARGET/$TIMESTAMP/$DATE" > /dev/null 2>&1
    then printf 'Attempt to copy file "%s" failed.\n' "$FILE"
    fi

presumably replacing the printf command with a call to logger . Instead of redirecting the cmp output to /dev/null you might want to save it in another file and also include the contents of that file with the data you send to logger .

1 Like

Hey, thank you very much!

So It would be:

if ! cmp "$FILE" "$TARGET/$TIMESTAMP/$DATE" > /dev/null 2>&1


logger -t sd-autocopy "copying of $FILE  failed"
    fi

Do I have to include the part \n' "$FILE" in the logger part?

Could you please check is this is right?

And how would you do the part with the log file?

You don't need to use a printf style format string operand with logger , but you do need a then in your if statement.

    if ! tmp "$FILE" "$TARGET/$TIMESTAMP/$DATE" > /dev/null 2>&1; then
	logger -t sd-autocopy "copying of $FILE failed"
    fi

I think it would also be wise to keep track of whether or not any copies failed and include an indication of success or failure in the notify-send at the end of the background job part of your script.

1 Like