Hallo, ich bin auf der Suche nach einem Skript für eine spezielle Aufgabe - vielleicht gibt es so etwas ja in Ansätzen, und jemand kann mir mit einem entsprechenden Hinweis ein wenig weiterhelfen... Das Skript soll eine gegebene Verzeichnisstruktur, z. B. /mnt/Projekte/Mitarbeiter/, rekursiv untersuchen, und für jede enthaltene Datei, die neuer als X Tage ist, in einem zweiten Verzeichnis, z. B. /mnt/Projekte/Aktuell/, einen symbolischen Link auf diese Datei erzeugen. Beispiel: Die Datei /mnt/Projekte/Mitarbeiter/Michael/Skripte/webserver.sh ist neuer als X Tage, dann soll das Skript unter /mnt/Projekte/Aktuell/Michael/Skripte/webserver.sh einen symbolischen Link auf diese Datei erzeugen. Gibt es so etwas schon, oder muß ich selbst skripten? Michael.
Am Montag, 18. Oktober 2004 16:57 schrieb Michael Schachtebeck:
Hallo,
ich bin auf der Suche nach einem Skript für eine spezielle Aufgabe - vielleicht gibt es so etwas ja in Ansätzen, und jemand kann mir mit einem entsprechenden Hinweis ein wenig weiterhelfen...
Das Skript soll eine gegebene Verzeichnisstruktur, z. B. /mnt/Projekte/Mitarbeiter/, rekursiv untersuchen, und für jede enthaltene Datei, die neuer als X Tage ist, in einem zweiten Verzeichnis, z. B. /mnt/Projekte/Aktuell/, einen symbolischen Link auf diese Datei erzeugen.
find ist dein Freund -> man find studieren und selber machen ;) MfG Mirko -- +--[ Mirko Richter (RHCE) ]------------------------+ | Networks & Communicationsystems | | Mirko Richter | | Ernst-Thaelmann-Str. 5, D-06774 Soellichau | | E-MAIL: m.richter@ngi.de | | Tel. +49/(0)34243/3369-50 \\\\ | | Fax. +49/(0)34243/3369-28 (O O) | +-----------------------------------oOOo-(_)-oOOo--+ Meine Auktionen bei hood.de: http://www.hood.de/nacmr%25dotcom.htm
Mirko Richter schrieb am 10/18/2004 05:07 PM:
Am Montag, 18. Oktober 2004 16:57 schrieb Michael Schachtebeck:
Das Skript soll eine gegebene Verzeichnisstruktur, z. B. /mnt/Projekte/Mitarbeiter/, rekursiv untersuchen, und für jede enthaltene Datei, die neuer als X Tage ist, in einem zweiten Verzeichnis, z. B. /mnt/Projekte/Aktuell/, einen symbolischen Link auf diese Datei erzeugen.
find ist dein Freund
-> man find studieren und selber machen ;)
Argh, das hatte ich auch probiert, bis ich eben noch ein letztes Mal die manpage studiert habe - mir war entgangen, daß die Tests atime/ctime/mtime nicht nur Parameter der Form n (*genau* n Tage), sondern auch +n (*mehr* *als* n Tage) und -n (*weniger* *als* n Tage) annehmen. Mir hat "find /pfad -mtime 3" nämlich nie die Dateien von heute ausgeworfen, daher meine Frage. Hat sich jetzt ja geklärt. :) Selbst schuld, wenn man die manpage nicht ordentlich liest... Michael.
Mirko Richter schrieb am 10/18/2004 05:07 PM:
find ist dein Freund
-> man find studieren und selber machen ;)
So, bin leider erst jetzt dazu gekommen, ich habe zwei Fragen zu dem Skript und hoffe auf ein paar Anregungen vin den Skriptexperten hier... Das Skript ist am Ende der Mail. Folgende Fragen: - Macht es den Unix-Befehlen etwas aus, wenn / mehrfach hintereinander vorkommt, also z. B. /bin/////bash? Auf meiner Kiste scheint das egal zu sein, aber ist das definiertes Verhalten der Bash, oder Zufall? - Welches Zeichen nehme ich fuer sed am besten als Trennzeichen anstatt /, das ja in jedem Pfad vorkommt? Ich habe vorerst = genommen (siehe Skript, aber ein = im Dateinamen ist natuerlich nicht verboten und fuehrt zur Fehlfunktion des Skripts. Waere schoen, wenn mir da jemand helfen koennte, ich bin in bash-Programmierung leider ueberhaupt nicht fit, C liegt mir mehr. ;) MfG, Michael. Und hier das Skript (ich hoffe, es wird hier nicht zerrissen); #!/bin/bash if [ "$#" -ne "3" ]; then echo "usage: $0 search_path target_path max_age" echo echo "searches search_path for all files newer than max_age days" echo "and creates links to them in target_path" exit 1 fi declare -i modus=0 # 0: Verzeichnis, 1: Dateiname # Da ln keine Option -p wie zum Beispiel mkdir bietet, muss # fuer jeden Link, der angelegt werden soll, zunaechst das # Zielverzeichnis erstellt und dann in einem zweiten Schritt # der Link angelegt werden. Um das moeglichst einfach zu # gestalten, gibt der find-Befehl zwei Zeilen aus: # - den kompletten Pfad der Datei ohne den Dateinamen (denn # mkdir braucht den Pfad ohne Dateinamen; wir schneiden aus # dem Pfad search_path heraus und fuegen stattdessen # target_path hinzu), # - den kompletten Dateinamen mit Pfad (als Parameter fuer ln). find $1 -type f -mtime -$3 -mindepth 2 -printf "%h\n%p\n" | \ while read input; do # falls die gelesene Eingabe ein Verzeichnis ist, # muss getestet werden, ob es existiert - falls nicht, # muss es neu angelegt werden if [ "$modus" -eq "0" ]; then # aufgeteilt auf 2 Befehle fuer den Fall $1 == $2 dir="`echo \"$input\" | sed -e "s=$1=="`" dir="`echo \"$2/$dir\" | sed -e "s=//=/="`" if [ ! -d "$dir" ]; then mkdir -p "$dir" fi modus=1 # falls die gelesene Eingabe eine Datei ist, muss # ein Link fuer sie angelegt werden; das Verzeichnis # wurde im vorherigen Durchlauf der Schleife bereits # angelegt, der Verzeichnisname steht noch in $dir else ln "$input" "$dir/" modus=0 fi done
Hallo, Am Wed, 20 Oct 2004, Michael Schachtebeck schrieb: [..]
- Macht es den Unix-Befehlen etwas aus, wenn / mehrfach hintereinander vorkommt, also z. B. /bin/////bash? Auf meiner Kiste scheint das egal zu sein, aber ist das definiertes Verhalten der Bash, oder Zufall?
Ist kein Zufall.
- Welches Zeichen nehme ich fuer sed am besten als Trennzeichen anstatt /, das ja in jedem Pfad vorkommt? Ich habe vorerst = genommen (siehe Skript, aber ein = im Dateinamen ist natuerlich nicht verboten und fuehrt zur Fehlfunktion des Skripts.
Üblich sind @, % und das Komma, aber die kommen mir zu oft vor. Ich selbst nehme ganz gerne §, ¶, ¡ oder ¿. Weitgehend auf der sicheren Seite bist du, wenn du ein Zeichen aus ASCII 1-31 verwendest, mit Ausnahme von LF und CR (ASCII 10 bzw. 13), z.B.: T="`echo -e '\1'`" echo 'fubar' | sed "s${T}u${T}x${T}g"
Und hier das Skript (ich hoffe, es wird hier nicht zerrissen);
[..]
find $1 -type f -mtime -$3 -mindepth 2 -printf "%h\n%p\n" | \
Quoten! find "$1" -type f -mtime "-${3}" -mindepth 2 -printf "%h\n%p\n" | \
while read input; do # falls die gelesene Eingabe ein Verzeichnis ist, # muss getestet werden, ob es existiert - falls nicht, # muss es neu angelegt werden if [ "$modus" -eq "0" ]; then # aufgeteilt auf 2 Befehle fuer den Fall $1 == $2 dir="`echo \"$input\" | sed -e "s=$1=="`" ^ ^ die inneren müssen auch escaped werden.
dir="`echo \"$input\" | sed -e \"s@$1@@\"`"
dir="`echo \"$2/$dir\" | sed -e "s=//=/="`"
dito. Außerdem willst du ein 'g' an den s-Befehl anhängen.
if [ ! -d "$dir" ]; then mkdir -p "$dir" fi
Hier ziehe ich: test -d "$dir" || install -d -m 755 "$dir" vor.
else ln "$input" "$dir/"
Du weißt, daß Hardlinks nur innerhalb einer Partition und nur mit Dateien funktioniert? Achso: ob das script das macht was es soll hab ich nicht überprüft. -dnh -- 37: Fehlertolerant Das Programm erlaubt keine Benutzereingaben.
Hallo, erstmal vielen Dank fuer die ausfuehrliche, professionelle und sehr konstruktive Kritik, die mir sehr weiterhilft! David Haller schrieb am 10/21/2004 05:45 AM:
Am Wed, 20 Oct 2004, Michael Schachtebeck schrieb:
find $1 -type f -mtime -$3 -mindepth 2 -printf "%h\n%p\n" | \
Quoten!
find "$1" -type f -mtime "-${3}" -mindepth 2 -printf "%h\n%p\n" | \
Hoffentlich keine dumme Frage: Was ist hier der Unterschied zwischen "$1" und "${3}"? man bash sagt mir: ${parameter} The value of parameter is substituted. The braces are required when parameter is a positional parameter with more than one digit, or when parameter is followed by a character which is not to be interpreted as part of its name. Eigentlich liegt hier doch keiner der beiden Faelle vor, oder? Die 3 ist nur eine einzelne Ziffer, und als einziges Zeichen folgt direkt das schliessende ", wie nach $1 auch...
if [ ! -d "$dir" ]; then mkdir -p "$dir" fi
Hier ziehe ich:
test -d "$dir" || install -d -m 755 "$dir"
vor.
Was ist der Vorteil von install gegenueber mkdir? Die Zugriffsrechte koennen ja beide Befehle mit dem Parameter -m setzen.
else ln "$input" "$dir/"
Du weißt, daß Hardlinks nur innerhalb einer Partition und nur mit Dateien funktioniert?
Ja, in diesem Fall ist das Absicht, weil das Verzeichnis fuer alle Mitarbeiter auch per ftp zugaenglich sein soll und DefaultRoot ~ mit Symlinks nicht funktioniert.
Achso: ob das script das macht was es soll hab ich nicht überprüft.
Zumindest die von mir gepostete Variante hat das - abgesehen von den Quoting-Problemen - getan. Ich werde es heute abend mit Deinen Tipps nochmal probieren und evtl. auftretende Probleme (die ich eigentlich nicht erwarte) hier posten. MfG, Michael.
Hallo, Am Thu, 21 Oct 2004, Michael Schachtebeck schrieb:
David Haller schrieb am 10/21/2004 05:45 AM:
Am Wed, 20 Oct 2004, Michael Schachtebeck schrieb:
find $1 -type f -mtime -$3 -mindepth 2 -printf "%h\n%p\n" | \
Quoten!
find "$1" -type f -mtime "-${3}" -mindepth 2 -printf "%h\n%p\n" | \
Hoffentlich keine dumme Frage: Was ist hier der Unterschied zwischen "$1" und "${3}"? man bash sagt mir: [..] Eigentlich liegt hier doch keiner der beiden Faelle vor, oder? Die 3 ist nur eine einzelne Ziffer, und als einziges Zeichen folgt direkt das schliessende ", wie nach $1 auch...
Ja, das ist genaugenommen nicht nötig, ich habe mir aber eben angewöhnt, _konsequent_ zu quoten und wenn ich etwas aus oder mit Variablen zusammensetze das ${} um den Variablennamen zu verwenden. Denn wenn da dann mal ein Fehler ist, ist sowas schwer zu finden. Der "Punkt" war hier aber das quoten. So bekommst du z.B. wenn $3 falsch belegt wäre eine aussagekräftigere Meldung: Ohne quoting um $3: $3="foo": find: invalid argument `-foo' to `-mtime' $3="1 2": find: paths must precede expression Letzteres bekommst du immer, wenn ein Leerzeichen in $3 ist. Mit quoting um $3: $3="foo": find: invalid argument `-foo' to `-mtime' $3="1 2": find: invalid argument `-1 2' to `-mtime' Bei der "Lösung" ohne Quoting ist man ziemlich gekniffen, wenn man den Fehler sucht.
if [ ! -d "$dir" ]; then mkdir -p "$dir" fi
Hier ziehe ich:
test -d "$dir" || install -d -m 755 "$dir"
vor.
Was ist der Vorteil von install gegenueber mkdir? Die Zugriffsrechte koennen ja beide Befehle mit dem Parameter -m setzen.
Stimmt. Ich dachte, daß install portabler als 'mkdir -p' sein könnte, aber 'install -d' ist wohl auch nicht überall vorhanden. Insofern ist das egal. Allerdings setzen 'install -d' und 'mkdir -p' die Rechte unterschiedlich, wenn die Verzeichnisse noch nicht existieren: $ rm -rf foo $ mkdir -m 750 -p foo/bar/baz $ find foo -ls 34287 4 drwxr-xr-x [..] foo 34426 4 drwxr-xr-x [..] foo/bar 34427 4 drwxr-x--- [..] foo/bar/baz $ rm -rf foo $ install -d -m 750 foo/bar/baz $ find foo -ls 34287 4 drwxr-x--- [..] foo 34426 4 drwxr-x--- [..] foo/bar 34427 4 drwxr-x--- [..] foo/bar/baz $ install -d -m 755 foo/bar/baz $ find foo -ls 34287 4 drwxr-x--- [..] foo 34426 4 drwxr-x--- [..] foo/bar 34427 4 drwxr-xr-x [..] foo/bar/baz $ mkdir -m 750 -p foo/bar/baz $ find foo -ls 34287 4 drwxr-x--- [..] foo 34426 4 drwxr-x--- [..] foo/bar 34427 4 drwxr-xr-x [..] foo/bar/baz $ rm -rf foo Welches Verhalten du willst musst du wissen ;) Ich habe mir übrigens auch angewöhnt 'test' auszuschreiben und nicht ' [ ' ... ' ]' zu verwenden.
else ln "$input" "$dir/"
Du weißt, daß Hardlinks nur innerhalb einer Partition und nur mit Dateien funktioniert?
Ja, in diesem Fall ist das Absicht
Ok. :) -dnh -- I used to be convinced that MicroSquish shipped crap because they simply didn't give a flying fuck as long as the sheep kept buying their shit. Now, I'm convinced that they really do ship the best products they are capable of writing, and *that's* tragic. -- John C. Randolph, on MS Quality.
Selber machen wird in diesem Fall wahrscheinlich schneller gehen als lange rumsuchen oder auf Antworten aus der Mailing-Liste warten ;) Hier ein Tipp: find -ctime +10 ! -type d -printf "`pwd`/%P\n" # sollte dir die Liste der gesuchten Dateien in einem Format ausgeben, das du an ln zur Verarbeitung weitergeben kannst. Viele Grüße, Patrick
Hallo, Am Mon, 18 Oct 2004, Patrick Nagel schrieb:
find -ctime +10 ! -type d -printf "`pwd`/%P\n" # sollte dir die Liste der gesuchten Dateien in einem Format ausgeben, das du an ln zur Verarbeitung weitergeben kannst.
Ungute Formulierung. Du gibst den Pfad nur implizit an und find kann den auch selber richtig ausgeben: find `pwd` -ctime +10 -not -type d -printf "%p\n" -dnh -- "Regiert wird rot, gearbeitet wird schwarz -- und nur geaergert wird sich noch gruen." -- Matthias Richling
participants (4)
-
David Haller
-
Michael Schachtebeck
-
Mirko Richter
-
Patrick Nagel