• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[gelöst] rsync: diff mit txt datei erzeugen?

fab.i.an

Member
Hallo Community

Ich möchte Ordner (mit Unterodnern und Dateien) von meinem Pc auf eine ext. Festplatte (oder USB Stick) kopieren. Da die Ordner auf der ext. Festplatte (oder USB Stick) aber immer wieder gelöscht werden, kann man mit rsync kein diff fahren. Ist es möglich das man eine Textdatei oder sowas erzeugt wo der inhalt des letzten kopierens enthalten ist. Und rsync daraus und anhand des quellverzeichnis einen diff macht? Nicht mehr vorhandene Ordner / Dateien in der Quelle aber in der TXT Datei können ignoriert werden. Ist sowas mit rsync möglich? Wenn nicht, wie kann man das Problem dann lösen?

Danke

Gruß Fabian
 

framp

Moderator
Teammitglied
So ganz klar ist mir nicht was Du willst. Kann es sein dass Du alle neuen/geänderten Dateien Deiner Festplatte auf ExtPlatte kopieren, die dann (warum auch immer :???: ) auf der ExtPlatte gelöscht werden und später nur noch die zum vorherigen Sync geänderten Dateien syncen?
 
OP
F

fab.i.an

Member
ja genauso hab ich mir das gedacht. :D Wenn das nicht mit rsync machbar ist vielleicht geht das ja dann mit einem anderen Programm?!
 

HBtux

Member
Ich verstehe zwar den Sinn nicht....

Du müsstest ein Script schreiben, das
- von allen Dateien eine Prüfsumme erzeugt und diese mit dem Dateinamen in ein Text-File schreibt.
- dann alle Files auf die Platte kopieren.

Bei den darauf folgenden Script-Aufrufen musst Du die Prüfsumme der Files mit den zuvor abgelegten Prüfsummen in der Textdatei vergleichen.
Wenn sich eine Datei verändert hat, die Datei einfach wieder kopieren....
 

framp

Moderator
Teammitglied
HBtux schrieb:
Ich verstehe zwar den Sinn nicht....
Geht mir ähnlich :roll:

Vielleicht machen wir mal einen Schritt zurück und Du sagst uns was eigentlich Dein Problem ist. U.U. finden wir eine andere (nicht rsync basierte) Lösung für Dein Problem ;)
 
OP
F

fab.i.an

Member
Also öfters kommt mein Vater mal zu mir oder Ich fahr nach Hause. Ich bring ihm dann immer Filme mit (Laptop oder USB Stick) oder wenn er kommt nimmt er sich die mit (Ext. USB Festplatte). So und da Ich nicht immer weiß welche Ich ihm schon mitgebracht habe (bei vorherrigen mal etc). Daher hab ich mir das so gedacht, dass rsync (oder ein anderes Programm) die schon mal mitgebrachten Fime in eine Liste schreibt, und dann nur die neuen noch nicht mitgebrachten auf Festplatte/Stick kopiert... (Diff also)
 

HBtux

Member
aha....
Gut, dann haben wir den Sinn auch mal verstanden.

Bei rsync gibt es einen Parameter
Code:
rsync --help
....
--exclude-from=FILE     exclude patterns listed in FILE
--include-from=FILE     don't exclude patterns listed in FILE
--cvs-exclude           auto ignore files in the same way CVS does
....
Du könntest ein kleines Script schreiben.
Dem Script übergibst Du den Dateinamen des Film, der kopiert werden soll.
Nach dem Kopieren schreibst Du den Dateinamen in die Exclude-Datei rein...
Beim nächsten rsync wird die Datei ausgelassen.

Alternativ könntest Du vor dem rsync noch per Script in die Exclude-Datei schauen und eine Meldung ausgeben "Der Film 'Avatar' wurde bereits am 09.03.2010 auf USB-to-Daddy kopiert.....
(Der Filmname mit dem Kopierdatum steht dann in der Exclude-Datei bzw. in einer zweiten Historie-Datei)
 

framp

Moderator
Teammitglied
Der Vorschlag von HBtux scheint mir eine mögliche Lösung zu sein. Das Script würde wohl irgendwas um die 10 Zeilen umfassen. Die Frage ist ob Du Dich mit bash Scripts auskennst ...
 

oc2pus

Ultimate Guru
fab.i.an schrieb:
Also öfters kommt mein Vater mal zu mir oder Ich fahr nach Hause. Ich bring ihm dann immer Filme mit (Laptop oder USB Stick) oder wenn er kommt nimmt er sich die mit (Ext. USB Festplatte). So und da Ich nicht immer weiß welche Ich ihm schon mitgebracht habe (bei vorherrigen mal etc). Daher hab ich mir das so gedacht, dass rsync (oder ein anderes Programm) die schon mal mitgebrachten Fime in eine Liste schreibt, und dann nur die neuen noch nicht mitgebrachten auf Festplatte/Stick kopiert... (Diff also)

nimm doch dieses Programm dazu:

Code:
The software is a combination of a comfortable backup program and an db based archive manager. StoreMan is ideal suited to backup / store files on NAS boxes or on USB disk drives - and for searching files without the need to have the storage devices permanently online. StoreMan is a Linux / Windows GUI - program, written in Python and based on the wxWidgets cross-platform Gui-library.

Pakete gibt es bei Packman:
http://packman.links2linux.de/package/StoreMan
 
OP
F

fab.i.an

Member
Also Ich habe mir StoreMan installiert, aber Ich bin da bis jetzt noch nicht so wirklich durchgestiegen.

Das mit dem Script hört sich ja auch nicht so schlecht an...aber Ich hab keine erfahrung im Script schreiben

Aber erstmal danke für die Antworten

Gruß Fabian
 

framp

Moderator
Teammitglied
fab.i.an schrieb:
... Das mit dem Script hört sich ja auch nicht so schlecht an...aber Ich hab keine erfahrung im Script schreiben
Code:
#!/bin/bash

function cleanup() {
   IFS=$SAVE_IFS                             # separator wieder in alten zustand setzen
}

trap 'cleanup' SIGHUP SIGINT SIGPIPE SIGTERM # rufe cleanup wenn script abbricht

MYSELF="${0##*/}"                            # hole den scriptnamen
SYNCED_FILES="$MYSELF.exclude"               # dateinname wo die gesyncten files gemerkt werden

SOURCE="test/source"                         # default quelle
DESTINATION="test/target"                    # default ziel

if [ $# == 2 ]; then                         # 2 parameter mitgegeben
   SOURCE=$1                                 # erster parameter ist quelle directory
   DESTINATION=$2                            # zweiter parameter ist ziel directory
fi

if [ -e $SYNCED_FILES ]; then                # falls datei mit den gesyncten files existiert
   EXCLUDE="--exclude-from=$SYNCED_FILES"    # baue exclude parameter für rsync
fi

if [ ! -e $SOURCE ]; then                    # prüfe on quellverzeichnis existiert
   echo "??? $SOURCE existiert nicht"
   exit 1
fi

if [ ! -e $TARGET ]; then                    # prüfe ob zielverzeichnis existiert
   echo "??? $SOURCE existiert nicht"
   exit 1
fi

FILES=$(rsync -rav $SOURCE $DESTINATION $EXCLUDE)  # sync u.U. mit exclude

find $DESTINATION -depth -type d -empty -exec rmdir {} \;   # lösche alle leeren directories

SAVE_IFS=$IFS                                # sicher alten bash sparator (ist space)
IFS=$(echo -en "\n\b")                       # setze separator zu newline oder backspace

I=0
LAST=0
for file in $FILES; do                       # zaehle wieviele einträge
   let LAST=LAST+1
done

let LAST=LAST-2

for file in $FILES; do                       # bearbeite alle files
   let I=$I+1
   if [[ $I -eq 1 || $I -gt $LAST ]]; then   # erste und die beiden letzten zeilen ignorieren
      continue
   fi

   let length=${#file}-1                     # letzte stelle des filenamens
   if [[ ${file:$length} != "/" ]]; then     # keine directories excluden (die enden mit /)
      echo "Synced $file"                    # meldung welche files gesynced wurde
      echo $file >> $SYNCED_FILES            # exclude das file
   fi
done

cleanup
<EDIT 031210>Etwas umgebaut um Fehler besser abzufangen</EDIT>
<EDIT 031410>Noch mal vollständig umgeschrieben</EDIT>
<EDIT 031610>Gab noch kleine Änderung wie das Löschen von leeren Verzeichnissen im Zielverzeichnis</EDIT>

Die Konstanten musst Du noch anpassen sowie die rsync Optionen. Ansonsten sollte es damit funktionieren. Du musst das Script allerdings immer aus dem Verzeichnis aufrufen, wo sich das Skript befindet. Kann man alles eleganter machen - aber ich denke es sollte für Deinen Fall reichen :roll:

Muss mich entschuldigen - aber es sind 3 Codezeilen mehr als ich geschätzt habe :D
 
OP
F

fab.i.an

Member
Ertmal danke für das Script

Ich hab es auch ausgeführt. Aber es gibt eine Fehlermeldung:
Code:
fabian@home:~> /home/fabian/Documents/Scripts/movies-copy.sh
touch: kann „syncDevice.done“ nicht berühren: Keine Berechtigung
**** FILM **** already synced

Mein Script sieht so aus:
Code:
#!/bin/bash

SOURCE=/home/fabian/Documents/movies/Cinema-only-source/*
DESTINATION=/home/fabian/Documents/movies/Cinema-only-destiny/
SYNCED_FILES="syncDevice.done"

touch $SYNCED_FILES     # falls es noch nicht existiert anlegen

for file in $(ls $SOURCE); do
   if $(grep $file $SYNCED_FILES 1>/dev/null); then
      echo "$file already synced"
   else
      echo $file >> $SYNCED_FILES
      echo "Syncing $file"
      rsync $file $DESTINATION
   fi
done

Hab ich da eventuell was Vergessen auszufüllen?
 

framp

Moderator
Teammitglied
Das ist merkwürdig. In der Datei syncDevice.done werden alle gesyncten Dateien gemerkt. Und da Du die erzeugst solltest Du auch touchen können.

Kannst Du mal den Output von ls -la in /home/fabian/Documents/Scripts posten?

Anyhow habe ich mir das Script noch mal angesehen und noch ein wenig robuster gemacht - d.h. es wird geprüft ob der rsync OK war und erst dann als kopiert gemerkt. Also oben noch mal geändert ;) .
 
OP
F

fab.i.an

Member
Code:
fabian@home:~> ls -la in /home/fabian/Documents/Scripts
ls: Zugriff auf in nicht möglich: Datei oder Verzeichnis nicht gefunden
/home/fabian/Documents/Scripts:
insgesamt 36
drwxr-xr-x  2 fabian users 4096 12. Mär 10:06 .
drwxr-xr-x 22 fabian users 4096  3. Mär 16:43 ..
-rwxr-xr-x  1 fabian users  152 30. Dez 18:24 backup.sh
-rwxr-xr-x  1 fabian users   48 14. Feb 15:13 boinc-manager.sh
-rwxr-xr-x  1 fabian users   46 13. Feb 20:13 boinc.sh
-rwxr-xr-x  1 fabian users 1592 28. Jun 2009  jdownloader.sh
-rwxr-xr-x  1 fabian users  457 12. Mär 10:06 movies-copy.sh
-rwxr-xr-x  1 fabian users   93  4. Mär 19:20 movies-tree.sh
-rwxr-xr-x  1 fabian users 1187 30. Dez 18:23 old_backup.sh
 

HBtux

Member
fab.i.an schrieb:
Code:
fabian@home:~> /home/fabian/Documents/Scripts/movies-copy.sh
touch: kann „syncDevice.done“ nicht berühren: Keine Berechtigung
Du stehts beim Ausführen des Scripts nicht in dem Verzeichnis, in dem das Script liegt....

Poste mal die Ausgabe der folgenden Befehle.... (von dem Verzeichnis aus, in dem Du Dich beim Testen befunden hast...)
Code:
pwd

ls -l `pwd` |head -n3

ls -l syncDevice.done
 
OP
F

fab.i.an

Member
Code:
fabian@home:~> pwd
/home/fabian
fabian@home:~> ls -l `pwd` |head -n3
insgesamt 71604
-rw-r--r--  1 fabian users    30227  2. Mär 11:45 00_mcfit.ods
-rw-r--r--  1 fabian users    20710 12. Mär 21:52 00_us serien.ods
fabian@home:~> ls -l syncDevice.done
-rw-r--r-- 1 root root 53 12. Mär 10:01 syncDevice.done
/home/fabian
 

framp

Moderator
Teammitglied
Der TE und ich haben uns offline ausgetauscht und das funktionierende Ergebnis habe ich oben noch mal updated. Sind jetzt doch ein paar mehr CodeZeilen geworden als 10 - nämlich 45 :(

Das Script kann auch hier runtergeladen werden.
 

HBtux

Member
fab.i.an schrieb:
Code:
fabian@home:~> ls -l `pwd` |head -n3
insgesamt 71604
-rw-r--r--  1 fabian users    30227  2. Mär 11:45 00_mcfit.ods
-rw-r--r--  1 fabian users    20710 12. Mär 21:52 00_us serien.ods

Kam nicht so eine ähnliche Ausgabe raus....?
(mich hatten die Rechte des lokalen Verzeichnisses interessiert...)
Code:
ls -l `pwd` |head -n3
total 71604
drwxr-xr-x  1 fabian users  4096 Oct 23 23:46 .
drwxr-xr-x  1 fabian users  8192 Mar 15 21:45 ..


fab.i.an schrieb:
Code:
fabian@home:~> /home/fabian/Documents/Scripts/movies-copy.sh
touch: kann „syncDevice.done“ nicht berühren: Keine Berechtigung

.....

fabian@home:~> ls -l syncDevice.done
-rw-r--r-- 1 root root 53 12. Mär 10:01 syncDevice.done
Die Datei "syncDevice.done" gehört "root root".
D.h. Du darfst sie als User "fabian" nicht beschreiben....

Entweder Eigentümer ändern oder die Rechte der Datei ändern.
 
OP
F

fab.i.an

Member
Also nach Email Verkehr mit Framp läuft das Script jetzt...Ich werde das Thema jetzt als gelöst markieren.:)

Code:
#!/bin/bash

#
# Kleines Shellscript um Dateien in zwei Verzeichnissen zu syncen
# Dabei können die Dateien im Zielverzeichnis gelöscht werden. Das
# Script merkt sich, welche Dateien kopiert wurden und synced die
# schon kopierten Dateien nicht mehr mit --exclude-from bei rsync.
#

function cleanup() {
   IFS=$SAVE_IFS                             			# separator wieder in alten zustand setzen
}

trap 'cleanup' SIGHUP SIGINT SIGPIPE SIGTERM 			# rufe cleanup wenn script abbricht

MYSELF="${0##*/}"						# hole den scriptnamen
SYNCED_FILES="$MYSELF.exclude"					# dateinname wo die gesyncten files gemerkt werden

SOURCE=/home/source			# quellverzeichnis
DESTINATION=/home/destination	# zielverzeichnis

if [ $# == 2 ]; then						# 2 parameter mitgegeben
	SOURCE=$1						# erster parameter ist quelle directory
	DESTINATION=$2						# zweiter parameter ist ziel directory
fi

if [ -e $SYNCED_FILES ]; then            			# falls datei mit den gesyncten files existiert
	EXCLUDE="--exclude-from=$SYNCED_FILES"			# baue exclude parameter für rsync
fi

if [ ! -e $SOURCE ]; then					# prüfe on quellverzeichnis existiert
	echo "??? $SOURCE existiert nicht"
	exit 1
fi

if [ ! -e $TARGET ]; then					# prüfe ob zielverzeichnis existiert
	echo "??? $SOURCE existiert nicht"
	exit 1
fi

FILES=$(rsync -rav $SOURCE $DESTINATION $EXCLUDE)		# sync u.U. mit exclude

find $DESTINATION -depth -type d -empty -exec rmdir {} \;	# lösche alle leeren directories

SAVE_IFS=$IFS                               			# sicher alten bash sparator (ist space)
IFS=$(echo -en "\n\b")                       			# setze separator zu newline oder backspace

I=0
LAST=0
for file in $FILES; do						# zaehle wieviele einträge
	let LAST=LAST+1
done

let LAST=LAST-2										

for file in $FILES; do						# bearbeite alle files
	let I=$I+1
	if [[ $I -eq 1 || $I -gt $LAST ]]; then			# erste und die beiden letzten zeilen ignorieren
		continue
	fi
	
	let length=${#file}-1					# letzte stelle des filenamens
	if [[ ${file:$length} != "/" ]]; then			# keine directories excluden (die enden mit /)
		echo "Synced $file"				# meldung welche files gesynced wurde
		echo $file >> $SYNCED_FILES			# exclude das file
	fi			
done

cleanup

danke für die Hilfe :D
 
Oben