ubuntuusers.de

Update/Sync-Skript Problem (rsync & diff)

Status: Gelöst | Ubuntu-Version: Ubuntu 10.04 (Lucid Lynx)
Antworten |

maze

Avatar von maze

Anmeldungsdatum:
28. Januar 2010

Beiträge: 144

Hi, ich hoffe mir kann wer helfen, bin ziemlich entnervt.. Ich muss andauernd von einem Server Dokumente laden und ausdrucken (natuerlich immer nur die neuen). Dazu habe ich mir folgendes Skript gebastelt:

#!/bin/bash
LOCAL=~/LOCALDIR/
LOCAL_TEMP=~/TMP/
PRINT=~/TO_PRINT/
SERVER=Benutzer@SERVERADRESSE:/home/SYNCDIR/DATEN_ZUM_DRUCKEN/
LOGFILE=$LOCAL/log/`date "+%Y%m%d%H%M"`
SYNC_CMD='rsync -vv -u -a -z --stats --progress'
touch $LOGFILE
$SYNC_CMD $SERVER $LOCAL | tee -a $LOGFILE
echo "\nDONE!\n\n"

Nun wuerde ich aber gern eine elegantere Variante finden, als staendig die ganzen Ordner durch zu sehen, wo was neues hinzugekommen ist, um neue Dokumente zu finden. Ich habe mir das dergestalt gedacht, das ich einfach das Update in einen temporaeren Ordner mache, dann zwischen diesem und meinem lokalen Zielverzeichnis ein diff mache, und die neuen Daten in ein Druckverzeichnis zu kopieren. Danach wuerde ich einfach nochmal zwischen dem tmp-Verzeichnis und dem Zielverzeichnis syncen (so brauche ich auch keine weitere Serververbindung) und fertig is die Sache. Nun habe ich mir dazu mal rsync und diff genauer und eingehender angesehen, und schliesslich folgendes gebaut:

#!/bin/bash
LOCAL=~/LOCALDIR/
SERVER=Benutzer@SERVERADRESSE:/home/SYNCDIR/DATEN_ZUM_DRUCKEN/
LOGFILE=$LOCAL/log/`date "+%Y%m%d%H%M"`
SYNC_CMD='rsync -vv -u -a -z --stats --progress'
touch $LOGFILE
$SYNC_CMD $SERVER $LOCAL_TEMP | tee -a $LOGFILE
cp -r `rsync -huazin --list-only $LOCAL_TEMP $LOCAL | grep '>f'` $PRINT
$SYNC_CMD $LOCAL_TEMP $LOCAL | tee -a $LOGFILE
thunar $PRINT

bei rsync bitte -n und --list-only vernachlaessigen, die sind nur fuer mich zum debuggen.

das problem ist das ausgabeformat von rsync:

.d..t...... e2.2/
>f+++++++++ e2.2/neu
.d..t...... e2.2/e3.2/
>f+++++++++ e2.2/e3.2/neu

aufgrund des >f+++++++++ kann cp mit der Dateiliste nichts anfangen. Weis jemand, was ich da tun kann, ober waehle ich schon einen ganz falschen Weg?

theinlein

Anmeldungsdatum:
29. Dezember 2007

Beiträge: 1279

Hallo,

evtl. verstehe ich etwas nicht ....

Frage: Kannst du nicht die Änderungen am letzten Änderungsdatum festmachen? rsync ändert doch eh nur das, was notwendig ist.

Ein diff verwendest du nicht.

Wenn dich das "f++++ " stört, dann willst du wahrscheinlich einfach das erste Wort weg haben; schreibe statt

... grep '>f'
...  awk '/>f/ { print $1; }' ...

maze

(Themenstarter)
Avatar von maze

Anmeldungsdatum:
28. Januar 2010

Beiträge: 144

theinlein schrieb:

Frage: Kannst du nicht die Änderungen am letzten Änderungsdatum festmachen? rsync ändert doch eh nur das, was notwendig ist.

ja, schon - aber eben dieses haendische nachschauen moechte ich mir ersparen (und angenommen ich koennte das aenderungsdatum gleich mit nem skript pruefen - ich weis ja kein datum.. ich will alle dateien, die neu hinzukommen.. und das is doch dann am einfachsten, wenn ich grade den sync mache, oder?)

Ein diff verwendest du nicht.

richtig, denn es lieferte mir auch nicht die ausgabe im gewuenschten format ☺

Wenn dich das "f++++ " stört, dann willst du wahrscheinlich einfach das erste Wort weg haben; schreibe statt

... grep '>f'
...  awk '/>f/ { print $1; }' ...

mit awk kenn ich mich nicht aus, ich habe das mal so uebernommen und bekomme folgende ausgabe:

awk: />f { print $1; }
awk:  ^ Nicht-beendeter Regulärer Ausdruck

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Zum einlesen in awk schlage ich dies vor: http://www-e.uni-magdeburg.de/urzs/awk/

Dein Fehler: jeder reguläre Ausdruck als Adresse, egal ob bei sed oder awk oder ... wird von "/" eingeschlossen, und bei Dir fehlt schlicht das zweite "/":

awk '/>f/ { print $1; }'

Allerdings wirft dieser Befehl nur das 1. Wort aus ... und Du wolltest doch eigentlich alles außer dem 1. Wort haben ?

Dann probier mal dies (das erste Wort wird einfach gelöscht):

awk '/>f/ { $1=""; print $0; }'

Macht das jetzt was Du haben willst ?

Sonst würde ich auch sagen, dass ein find mit Zeit-Parameter hier sehr viel mehr Sinn macht. Natürlich musst Du dafür eine Zeitreferenz schaffen, aber da reicht ja ein simples touch auf eine Protokoll-Datei. (immer wenn ein neuer Zeitabschnitt anfangen soll)
Oder kommen gelegentlich auch Dateien mit älterem Zeitstempel dazu ? - dann geht das natürlich nicht.

LG,

track

theinlein

Anmeldungsdatum:
29. Dezember 2007

Beiträge: 1279

Ja, da hat awk recht: Du hast den zweiten Schrägstrich vergessen.

Bei awk ist das so:

/pattern/  { code }

wendet den "code" auf die Zeilen an, auf die das 'pattern' passt

/pattern1/, /pattern2/   { code }

wendet den "code" auf alle Zeilen an, auf die das 'pattern1' passt, dann die nachfolgenden Zeilen, bis zu einer Zeile, auf die pattern2 passt - also auf Blöcke, die durch ein Anfangs- und ein Endmuster begrenzt werden. Sooft das halt in der Datei / in den Dateien vorkommt.


Zum Problem:

warum gehst du nicht die Dateien durch (Änderungsdatum), machst ein rsynch und dann stellst du das neue Änderungsdatum fest?

# vorher
# Dateiformat: je Zeile Änderungszeitpunkt, senkrechter Strich, Dateiname
find myDir  -type f   -printf "%t | %p"  >  vorher.log
rsync .....

# nachher
find myDir  -type f   -printf "%t | %p"  >  nachher.log

# nur die unterschiedlichen Zeilen ausfiltern, doppelte sind dann weg
cat vorher.log nachher.log | sort | uniq -u  > unterschiedliche.log

# die Dateinamen behalten
awk -F '|'  '{ print $1; }'  unterschiedliche.log  | uniq -d  > modifizierte.log
awk -F '|'  '{ print $1; }'  unterschiedliche.log  | uniq -u  > neue.log

Das Ganze kann man natürlich gleich verketten. Mit den Zwischenergebnissen in eigenen Files kannst du das besser nachvollziehen.

maze

(Themenstarter)
Avatar von maze

Anmeldungsdatum:
28. Januar 2010

Beiträge: 144

Danke Leute, ihr habt mir damit echt weitergeholfen - awk is ein feines tool ☺

meine finale Version sieht nun so aus (falls jm. mal ein aehnliches Problem haben sollte):

#!/bin/bash
LOCAL=~/LOCALDIR/
SYNC=~/SYNC/
if !(test -d $SYNC); then mkdir $SYNC; fi
SERVER=Benutzer@SERVERADRESSE:/home/SYNCDIR/DATEN_ZUM_DRUCKEN/
SYNC_CMD='rsync -huazi --progress'

find $LOCAL -type f -printf "%p | %t\n" > $SYNC/vorher.log
$SYNC_CMD $SERVER $LOCAL
find $LOCAL -type f -printf "%p | %t\n" > $SYNC/nachher.log

for FILE in `cat $SYNC/vorher.log $SYNC/nachher.log | sort | uniq -u | awk -F '|' '{ print $1; }' | uniq` ; do
  cp $FILE $SYNC
done
rm $SYNC/*.log
nohup thunar ./printerer/

zugegebendermaszen bei dir theinlein zum grossen teil abgekupfert ☺

..beruht allerdings darauf, das keine aelteren files auf den server geschoben werden.

aber zwei Fragen hab ich noch - wieso bleibst mein terminal haengen, obwohl ich nohup nutze? Und: ist das letzte uniq eigentlich noetig? ich mein, ich hab ja vorher schon eines drin...

theinlein

Anmeldungsdatum:
29. Dezember 2007

Beiträge: 1279

Hi, (ich beziehe micd er Einfachheit halber auf meinen Post ...)

die Vereinigung von vorher.log und nachher.log führt doch dazu, dass zuvor bereits vorhandene Dateien zweimal auftauchen: Einmal mit einer Zeile mit altem Zeitstempel und einmal mit neuem Zeitstempel oder es sind zwei identische Zeilen, weil sich nichts geändert hat. Die neuen Dateien tauchen nur mit je einer Zeile auf.

Mit

cat vorher.log nachher.log | sort | uniq -u  > unterschiedliche.log

werden nur die unterschiedlichen Zeilen ausgegeben, nicht die doppelten - also hat man alle Änderungen, aber es kommte jede geänderte Datei zweimal vor und nur die Neuen sind mit einer Zeile vertreten.

Deshalb anschließend die Unterscheidung zwischen modifizierte.log und neue.log. modifizierte.log enthält alle Zeilen, die vorher doppelt vorkamen (jetzt nur die Dateinamen ohne Zeitstempel verglichen, deshalb awk dazwischen) und neue.log alle, die nur als einzelne Dateien/Zeilen vorkamen.

maze

(Themenstarter)
Avatar von maze

Anmeldungsdatum:
28. Januar 2010

Beiträge: 144

ah, ok, hab's kapiert, thx ☺

was mit nohup is weist du nciht auch zufaellig, oder? weil manchmal geht's und manchmal nich.. wenn's nicht geht, seh ich im fenster noch diese ausgabe:

nohup: ignoriere Eingabe und hänge Ausgabe an „nohup.out“ an

theinlein

Anmeldungsdatum:
29. Dezember 2007

Beiträge: 1279

Hi,

nohup bewirkt, dass das Signal SIGHUP (hang up signal) nicht an das Script weitergereicht wird und somit das Script nicht beendet wird. Man kann auch im Script ein 'trap' verwenden und das nohup dann weglassen.

Ein SIGHUP wird erzeugt, wenn man das Terminal abmeldet - sich z.B. ausloggt. Damit werden alle Prozesse des Users, die mit diesem Terminal zusammenhängen beendet. Will man einen Prozess starten, der nicht mit logout beendet wird, muss man nohup oder trap verwenden.

nohup hängt die Ausgaben des mit nohup gestarteten Programmes an die Datei nohup.out an, anstatt auf das nun nicht mehr zur Verfügung stehende Terminal zu schreiben.

Frage: was meinst du denn mit: "Wieso bleibt mein Terminal hängen?"

Was passiert denn da genau?

maze

(Themenstarter)
Avatar von maze

Anmeldungsdatum:
28. Januar 2010

Beiträge: 144

theinlein schrieb:

...muss man nohup oder trap verwenden...

was ist trap? ich hab das nur schon mal zusammen mit interrupts gelesen und man trap ergab auch keinen treffer..

"Wieso bleibt mein Terminal hängen?"- Was passiert denn da genau?

naja, im grunde nicht's ausser der Ausgabe, die ich in meinem vorherigen Post erwaehnt habe. Leider bleibt das Terminal halt trotzdem geoeffnet.. bzw. der Promt taucht solange nicht wieder auf, bis ich den filebrowser (also den aktiven prozess) wieder beendet habe.. allerdings ist das, wie gesagt, nicht immer der Fall. Manchmal funktioniert es auch wie du es beschreibst, und wie ich glaube, das es seien soll.

theinlein

Anmeldungsdatum:
29. Dezember 2007

Beiträge: 1279

maze schrieb:

naja, im grunde nicht's ausser der Ausgabe, die ich in meinem vorherigen Post erwaehnt habe. Leider bleibt das Terminal halt trotzdem geoeffnet..

Weder nohup noch die Verwendung von Traps werden dein Fenster schließen.

maze schrieb:

bzw. der Promt taucht solange nicht wieder auf, bis ich den filebrowser (also den aktiven prozess) wieder beendet habe...

Meinst du jetzt mit Filebrowser dein Script? Oder wie hast du dein Programm gestartet?

maze schrieb:

allerdings ist das, wie gesagt, nicht immer der Fall. Manchmal funktioniert es auch wie du es beschreibst, und wie ich glaube, das es seien soll.

Hab ich es beschrieben?

Zu trap:

Wenn man man trap macht öffnet sich die Beschreibung der bash Shell, da trap ein biult-in-Command ist, kein Shell-externer Prozess.

trap -l

listet alle Signal auf.

trap  "" SIGHUP

am Anfang des Scripts bewirkt das "NICHTS" als Folge des Eintreffens von SIGHUP.

maze

(Themenstarter)
Avatar von maze

Anmeldungsdatum:
28. Januar 2010

Beiträge: 144

gehe davon aus, ich habe folgendes skript namnes 'test.sh':

#!/bin/bash
nohup thunar

und nun lege ich einen starter mit diesem kommando an:

bash /../test.sh

nun wuerde ich erwarten, das das temrinalfenster aufpopt, dann thunar aufgaht, und sich das terminal fenster wieder schliesst, waehrend thunar offen bleibt.

eben das klappt nur sporadisch.. in der anderen haelfte der faelle bleibt das terminal geoeffnet, bis ich thunar schliesse.

Zu trap:

Wenn man man trap macht öffnet sich die Beschreibung der bash Shell, da trap ein biult-in-Command ist, kein Shell-externer Prozess.

ich@pc:~$ man trap
No manual entry for trap
ich@pc:~$ 
trap -l

...geht allerdings, nur kann ich damit nix anfangen, da ich keine beschreibung von trap habe..

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

maze schrieb:

Zu trap:

... , da ich keine beschreibung von trap habe..

??? - - ja, und ??   –> einmal suchen: auf Google

liefert bei mir als erstes: http://linux.die.net/man/1/trap 😉

LG,

track

maze

(Themenstarter)
Avatar von maze

Anmeldungsdatum:
28. Januar 2010

Beiträge: 144

track schrieb:

http://linux.die.net/man/1/trap 😉

ok, danke erstmal.. aber nun bin ich etwas verwirrt.. wieso habe ich diese man-page nicht auf meinem rechner, wenn ich trap drauf habe..?

dachte, wenn ein program installiert wird, wird auch seine man-page automatisch mitinstalliert?

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

... ganz einfach:

track@ubuntu:~$ type trap
trap is a shell builtin

und für Shell- interne Funktionen gibt es auch keine externe man-page, sondern nur den (internen) help-Aufruf:

help trap

Die Internet-Version mogelt da ein bisschen ...

LG,

track

Antworten |