ubuntuusers.de

backup script mit find und wenn Datei vorhanden dann hänge ein +1 dran

Status: Ungelöst | Ubuntu-Version: Ubuntu 14.04 (Trusty Tahr)
Antworten |

OpSi

Anmeldungsdatum:
11. Januar 2009

Beiträge: Zähle...

Wohnort: Ulm

Einen wunderschönen Guten Abend,

habe mir hier folgendes zusammen gebastelt, es macht so weit auch das was ich möchte.

In dem Ordner befinden sich Datein ohne Dateityp, also a b c d e f g als test. Später sollen es dann Dateien mit verschiedenen Dateitypen sein.

1
2
3
4
5
6
#!/bin/bash

for file in $(find . /home/opsi/files -type f -mmin -20 -exec bash -c 'echo "$1"' _ {} \;);
  do
    cp -auv /home/opsi/files/$1 /media/backup
  done

Jetzt würde ich ihm noch gerne sagen, wenn sich Dateien verändern und diese sich schon im Backup Ordner befinden, hänge eine +1 bis höchstens +30 dran.

1
2
3
4
5
# Wenn ich das richtig verstanden hab, wird der Inhalt von "{}"

-exec bash -c 'echo "$1"' _ {} \;

# in die Variable $1 gespeichert

Jetzt könnte ich ja mit einer if Abfrage sagen, das er prüfen soll, ob die Dateien schon im Ordner vorhanden sind. Wenn ja, dann prüfe auf letzte Versions Nummer und hänge eine +1 dran.

Ich hatte es mal versucht

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/bin/bash

for file in $(find . /home/opsi/files -type f -mmin -100 -exec bash -c 'echo "$1"' _ {} \;);
do
if # hier weiß ich nicht was ich rein schreiben soll;
	then
		# mv "$1" "$(printf "%s" "$1" | sed 's/$/_1/g')"
		mv "$1" "${1}_1"
		ln "${1}_1" /media/backup2
	else
		ln "$1" /media/backup2
	fi

done

Ist leider nix dabei heraus gekommen, muss dazu sagen von Shell Programmierung, hab ich keine Ahnung. Alles durch viel lesen und probieren hinbekommen, naja sofern ich überhaupt was hinbekommen hab. 😳

MfG Tino

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17621

Wohnort: Berlin

Find iteriert über die Dateien, die den Kriterien genügen, die Du mitgibst. Diese Dateien an eine For-Schleife zu reichen, die dann ihrerseits darüber iteriert, ist i.d.R. eine überflüssige Gymnastik, die an der Schnittstelle nur unnötige Fehlermöglichkeiten erzeugt.

Schreib doch ein Skript, welches eine beliebige Datei in der gewünschten Weise behandelt, und rufe dies gleich von find aus auf:

1
find . /home/opsi/files -type f -mmin -20 -exec linkIfLt30.sh {} \;

linkIfLt30.sh:

1
2
3
#!/bin/bash
datei=$1
# ...

Ob eine Datei existiert kann man mit test -e DATEI testen.

OpSi

(Themenstarter)

Anmeldungsdatum:
11. Januar 2009

Beiträge: 33

Wohnort: Ulm

Danke für die schnelle Antwort, jetzt bin ich noch verwirrter als vorher. ☹

Also schreib ich dann das if etc in die linkIfLt30.sh? Ok wenn ja, wie fange ich da am besten an?

Sry, wie gesagt ich hab keine blassen Schimmer von der Materie.

schusch

Avatar von schusch

Anmeldungsdatum:
2. September 2008

Beiträge: 324

Wohnort: Berlin

Versuche es mal so (nicht getestet, beware of Tippfehler ☺, Dateipfade werden nicht kopiert!)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/bash
backup=/media/backup
# pwd merken
hierwarich=$(pwd)
cd $backup
for file in $(find . /home/opsi/files -type f -mmin -20); do
  datei=$(basename $file)
# fragen, ob Datei existiert
  if [ -f $datei ]; then
    nr=1
    while [ -f "$datei"_"$nr" && $nr -lt 30]; do
      nr=$(($nr+1))
    done
# in $nr steht jetzt die erste freie Nummer, oder 30, falls es "$datei"_30 schon gibt
# rückwärts die Dateien umbenennen
    while [ $nr -gt 1]; do
      cp "$datei"_$(($nr-1)) "$datei"_$(($nr))
      nr=$(($nr-1))
    done
# jetzt noch $datei nach "$datei"_1
    cp $datei "$datei"_1
  fi
#  die Datei kopiren
  cp $file .
done  # zu for Schleife
#  zurück wo ich war
cd $hierwarich

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17621

Wohnort: Berlin

Ja.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
f="$1" 
if [[ ! -e backup/"$f" ]]
then
  for postfix in _{1..5}
  do
    if [[ ! -e backup/"$f"$postfix ]]
    then
      echo mv "$f" backup/"$f"$postfix
      break
    fi
  done
fi

Zum Testen läuft hier die Nummerierung nur von 1 bis 5, nicht 30. Statt ln oder mv macht der Code nur eine echo. Der else-Block außen fehlt noch, um für den Fall, dass noch keine unnummerierte existiert, die Datei ohne Nummer zu kopieren/moven/grooven/linken.

Update: Musste noch einen Testnamen in $f ändern und das $f quoten.

OpSi

(Themenstarter)

Anmeldungsdatum:
11. Januar 2009

Beiträge: 33

Wohnort: Ulm

Erst einmal Vielen Dank euch zwei. 👍

Werde auch mit allen zwei Lösungen testen. ♥

@schusch

Einmal ausgeführt alles bestens, beim zweiten mal meckerte er und beim 3. mal das selbe usw.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
root@eBook:/home/opsi/bckscript# ./script2.sh 
root@eBook:/home/opsi/bckscript# ./script2.sh 
./script2.sh: Zeile 12: [: Fehlende »]«
./script2.sh: Zeile 17: [: Fehlende »]«
cp: »./a“ und »./a“ sind die gleiche Datei
./script2.sh: Zeile 12: [: Fehlende »]«
./script2.sh: Zeile 17: [: Fehlende »]«
root@eBook:/home/opsi/bckscript# ./script2.sh 
./script2.sh: Zeile 12: [: Fehlende »]«
./script2.sh: Zeile 17: [: Fehlende »]«
cp: »./a_1“ und »./a_1“ sind die gleiche Datei
./script2.sh: Zeile 12: [: Fehlende »]«
./script2.sh: Zeile 17: [: Fehlende »]«
cp: »./a“ und »./a“ sind die gleiche Datei
./script2.sh: Zeile 12: [: Fehlende »]«
./script2.sh: Zeile 17: [: Fehlende »]«

#######################################################################################################################

root@eBook:/home/opsi/bckscript# ls backup
a  a_1  a_1_1  a_1_1_1  a_1_1_1_1  

Hab in Zeile 12 zwischen Zahl 30 und ] ein Leerzeichen gemacht, sowie in Zeile 17 bei 1 und ].

Jetzt sieht es so aus, versteh es nicht, Leerzeichen ist doch da.

1
2
3
root@eBook:/home/opsi/bckscript# ./script2.sh 
./script2.sh: Zeile 12: [: Fehlende »]«
cp: »./a_1_1“ und »./a_1_1“ sind die gleiche Datei

@user_unknown

Es macht nichts und zeigt mir auch keinen Fehler an, ich schaff das noch, werde mich dann noch mal melden.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17621

Wohnort: Berlin

Du brauchst vielleicht einen Bash-shebang wenn Du es direkt aufrufst.

Wie rufst Du es auf?

OpSi

(Themenstarter)

Anmeldungsdatum:
11. Januar 2009

Beiträge: 33

Wohnort: Ulm

Ich rufe es wie folgt auf

Das hab ich files1.sh genannt

1
2
3
#!/bin/bash

find . /home/opsi/bckscript/files -type f -mmin -20 -exec /home/opsi/bckscript/script1.sh {} \;

und das script1.sh genannt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/bin/bash

f="$1"
if [[ ! -e backup/"$f" ]]
then
  for postfix in _{1..5}
  do
    if [[ ! -e backup/"$f"$postfix ]]
    then
      echo mv "$f" backup/"$f"$postfix
      break
    fi
  done
fi

Bei der Ausführung zeigt er mir folgendes an. Ich hab alles mögliche schon mit Pfaden anpassen versucht, bin glaub bissel zu blöd dafür.

1
2
3
4
root@eBook:/home/opsi/bckscript# ./files1.sh 
mv ./files/a backup/./files/a_1
mv ./script1.sh backup/./script1.sh_1
mv /home/opsi/bckscript/files/a backup//home/opsi/bckscript/files/a_1

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17621

Wohnort: Berlin

Ah so.

Das meinte ich mit:

Zum Testen läuft hier die Nummerierung nur von 1 bis 5, nicht 30. Statt ln oder mv macht der Code nur eine echo.

Wenn die angezeigten Befehle das sind, was Du tun wolltest, dann muss das 'echo' vor dem 'mv' weg. Und das mit dem Linken muss noch hin, und Dein Backuppfad sieht anders aus:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/bin/bash

f="$1"
if [[ ! -e /media/backup2/"$f" ]]
then
  for postfix in _{1..5}
  do
    if [[ ! -e /media/backup2/"$f"$postfix ]]
    then
      mv "$f" "$f"$postfix
      ln "$f"$postfix /media/backup2/"$f"$postfix
      break
    fi
  done
fi

OpSi

(Themenstarter)

Anmeldungsdatum:
11. Januar 2009

Beiträge: 33

Wohnort: Ulm

@user_unknown

Der von Dir zuletzt gepostete Code, löscht die zwei Orginalen .sh Dateien und erstellt mir zwei neue mit _1 hinter dem sh. Er kopiert mir alles mögliche, aber nicht die Dateien im Verzeichniss files/.

Ich saß von gestern bis jetzt dran und hab alles mögliche versucht, ich bekomm es einfach net hin. 😢

Sry Noob on Tour!!!

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17621

Wohnort: Berlin

Der von Dir zuletzt gepostete Code, löscht die zwei Orginalen .sh Dateien und erstellt mir zwei neue mit _1 hinter dem sh. Er kopiert mir alles mögliche, aber nicht die Dateien im Verzeichniss files/.

Gelöscht wird gar nichts, es wird ein mv gemacht. Das war ja Deine Anforderung, dass man die Datei umbenennt nach *_1.

Deswegen bekommt man auch eine _1_1-Datei im zweiten Schritt, denn das Original hat man ja umbenannt.

Vielleicht hast Du auch im else-Zweig nichts angegeben. Oder ich habe falsch verstanden, was Du machen willst.

Ich habe jetzt experimentiert und mit eigenen Pfaden und Konditionen getestet.

1
find . -type f -mmin -20 -name "d*" -exec ./movenlink.sh {} \;
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/bash
f="$1"

tgt=~/proj/mini/forum/test

if [[ -e $tgt/"$f" ]]
then
  echo "Datei $f existiert" 
  for postfix in _{1..5}
  do
    if [[ ! -e $tgt/"$f"$postfix ]]
    then
      mv "$f" "$f"$postfix
      ln "$f"$postfix $tgt/"$f"$postfix
      break
    else      
      echo "postfix $postfix existiert" 
    fi
  done
else
  echo neu $f
  ln "$1" $tgt/
fi

Jetzt würde ich ihm noch gerne sagen, wenn sich Dateien verändern und diese sich schon im Backup Ordner befinden, hänge eine +1 bis höchstens +30 dran.

Dateien ändern sich selten selbst. Wenn also jmd. die Datei geändert hat - damit meinst Du den Inhalt, prüfst mit mmin - und sich schon im Backupordner befindet (also nicht die Datei, sondern eine gleichen Namens), dann hänge eine _1 an. Tja, wenn man das macht dann hat man keine Datei dieses Namens mehr. Aus a wird a_1. Dann willst Du einen Link setzen, und beim nächsten Lauf, wenn die Datei jünger ist als 20 Minuten, gibt es eine solche Datei schon, und Du machst daraus a_1_1. Linkst wieder. Dann a_1_1_1 usw.

OpSi

(Themenstarter)

Anmeldungsdatum:
11. Januar 2009

Beiträge: 33

Wohnort: Ulm

Sry mein Fehler, hätte es besser erklären müssen.

Ich versuch es noch mal, es gibt einen Ordner der heißt files.

 ~/files
     -a
     -b
     -c
     -d

Später sollen die auch mal verschiedene Dateitypen haben.

Jetzt hab ich mir für Testzwecke eine Partition angelegt, das ein NAS darstellen soll, wie es auch später mal sein soll.

/mnt/backup
    -a
    -a_1   # später dann mal a.text a_1.txt a_2.txt
    -a_2
    -b
    -c
    -c_1
    -d

Er soll prüfen ist Datei vorhanden, wenn nicht kopiere sie hin, wenn ja dann nenne sie um und kopiere sie dann erst.

Die Orginal Datei soll bestehen bleiben, da wäre ja ein cp schon besser, oder?

Der Code von Schusch macht soweit das, wie ich es haben wollte, außer das er auch dieses a_1 a_1_1 anlegt.

Dieses zu ändern oder Dein Script zum laufen zu bringen, dazu fehlt mir einfach das nötige Wissen.

Des wegen kauf ich mir folgendes Buch (Linux-Kommandoreferenz: Shell-Befehle von A bis Z (Galileo Computing)), hoffe ich kann mir damit etwas Grundwissen anlernen.

Hoffe es ist ein wenig verständlicher!!!

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17621

Wohnort: Berlin

OpSi schrieb:

Er soll prüfen ist Datei vorhanden, wenn nicht kopiere sie hin, wenn ja dann nenne sie um und kopiere sie dann erst.

Die Orginal Datei soll bestehen bleiben, da wäre ja ein cp schon besser, oder?

Wenn Du sie umbenennst ist der Originalname weg. Ich denke Du willst die Datei kopieren aber ihr einen neuen, durchnummerierten Namen dabei verpassen. Das heißt Du gibst beim Kopieren den neuen Namen an.

Man kann das ja mal an einer Datei a durchspielen, die anfangs neu ist. Das Backupverzeichnis backup sei leer:

a
backup/

a
backup/a

a
backup/a
backup/a-1

a
backup/a
backup/a-1
backup/a-2

...

a
backup/a
backup/a-1
...
backup/a-30

? 

Jetzt hast Du Hardlinks gezeigt. Diese ändern sich aber mit dem Ändern der Ursprungsdatei mit. So hättest Du am Ende 30 identische Dateien im Backupverzeichnis, nur mit unterschiedlichen Namen. Das willst Du wahrscheinlich nicht. Die Frage wäre, wie Du auf die Idee mit den Links gekommen bist.

OpSi

(Themenstarter)

Anmeldungsdatum:
11. Januar 2009

Beiträge: 33

Wohnort: Ulm

30 identische Dateien, wäre nicht mein Ziel, das zählt dann unter die Kategorie Paranoide Datensicherung. 🤣

Da ich keine Ahnung von der Materie habe, hab ich das mit den Links im Internet gefunden und einfach mal ein bisschen damit getestet.

Ja genau so wie dein Beispiel sollte es sein.

\\EDIT// Dateien zu prüfen mittels mmin wäre nicht so sinnvoll, da die Warscheinlichkeit Groß ist, dass er Dateien übersieht wenn ich das Script nicht alle 19 min laufen lass. Besser wäre doch da .md5 geeignet, da sich ja der Hashwert einer Datei beim verändern der Datei ändert, oder liege ich da flasch.

OpSi

(Themenstarter)

Anmeldungsdatum:
11. Januar 2009

Beiträge: 33

Wohnort: Ulm

Wie müsste ich es denn schreiben, dass er mir anstatt backup und .tgz, alles durch sucht.

1
2
3
4
5
6
set -- ${BACKUPDIR}/backup-???.tgz
lastname=${!#}
backupnr=${lastname##*backup-}
backupnr=${backupnr%%.*}
backupnr=${backupnr//\?/0}
backupnr=$[10#${backupnr}]
Antworten |