BlackBoxCoder
Anmeldungsdatum: 19. Juni 2013
Beiträge: 22
|
Hallo Freunde der Nacht, ich habe mal ein kleines Problem mit einem kleinen Script. Ich habe ein Script geschrieben, dass mittels imagemagick Bilder aus einem Ordner verkleinert und in einen unterordner verkleinert speichert. Das funktioniert auch soweit ganz gut. Ich möchte in einer For-Schleife aber alle gängigen Datentypen abfangen, sprich: jpg, jpeg, bmp und png.
Dies mache ich mittels for i in *.{jpg,jpeg,png,bmp} Interessanterweiße versucht nun aber mein Script die convert operation von imagemagick auch auf alle Dateitypen anzuwenden, auch wenn diese nicht im Verzeichnis vorhanden sind. Hier die Beispielausgabe: sudo ./thumber.sh /home/blackboxcoder/ 150 150
convert.im6: unable to open image `/home/blackboxcoder//*.jpeg': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no images defined `/home/blackboxcoder//thumb/*.jpeg' @ error/convert.c/ConvertImageCommand/3044.
convert.im6: unable to open image `/home/blackboxcoder//*.bmp': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: no images defined `/home/blackboxcoder//thumb/*.bmp' @ error/convert.c/ConvertImageCommand/3044.
convert.im6: unable to open image `/home/blackboxcoder//*.png': No such file or directory @ error/blob.c/OpenBlob/2638.
convert.im6: unable to open file `/home/blackboxcoder//*.png' @ error/png.c/ReadPNGImage/3667.
convert.im6: no images defined `/home/blackboxcoder//thumb/*.png' @ error/convert.c/ConvertImageCommand/3044.
converting done! Hier das entsprechende Script:
| #!/bin/bash
if [ $# -gt 2 ]; then #check if there are more parameter then 2
mkdir -p $1/thumb #create dir thumb if not exits
for i in $1/*.{jpg,jpeg,bmp,png}; #for each jpg,jpeg,bmp,png in the dir do
do
convert $1/${i##*/} -resize $2x$3 $1/thumb/${i##*/} #convert picture
done
echo "converting done!"
fi
|
Ich hoffe ihr könnt mein Problem verstehen und habt den ein oder anderen Tipp für mich. Viel Dank!
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13217
|
Du brauchst die Bash-Option "nullglob" oder Du musst testen, ob die Datei existiert (Zeilen 10 und 13 einkommentieren). Ich würde auch die Variablen quoten: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | #!/bin/bash
shopt -s nullglob
if [ $# -gt 2 ]; then #check if there are more parameter then 2
target="$1/thumb"
mkdir -p "$target" #create dir thumb if not exits
for i in "$1"/*.{jpg,jpeg,bmp,png}
do
# if [ -f "$i" ]; then
base="${i##*/}"
convert "$1/$base" -resize "$2x$3" "$target/$base"
# fi
done
echo "converting done!"
fi
|
Ich habe auch noch die redundanten Kommentare weggelassen. Ciao robert
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13217
|
PS: Noch etwas: ich würde die Fehlerbehandlung anders machen, so dass das Skript oben gleich aussteigt: | if [ $# -lt 3 ]; then
echo "ERROR: need three arguments." >&2
exit 1
fi
target="$1/thumb"
mkdir -p "$target" #create dir thumb if not exits
...
|
So sparst Du Dir die Einrückung für den Hauptteil und man muss nicht bis unten lesen, um zu sehen, was im Fehlerfall passiert.
|
BlackBoxCoder
(Themenstarter)
Anmeldungsdatum: 19. Juni 2013
Beiträge: 22
|
Wow, danke für die direkte Antwort. Ich denke ich werde die Variante nehmen, in der geprüft wird, ob die Datei vorhanden ist. Das mit dem frühen Abbruch ist ebenfalls sehr gut. Danke dafür, wird morgen gleich getestet. Gute Nacht, BBC
|
Benno-007
Anmeldungsdatum: 28. August 2007
Beiträge: 29240
Wohnort: Germany
|
Haha, das Problem hatte ich beim selben Zweck auch. 😉 Hab dann auch die Existenz abgeprüft. Die Tests hatten mich eine Menge Zeit gekostet.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13217
|
BlackBoxCoder schrieb: Wow, danke für die direkte Antwort. Ich denke ich werde die Variante nehmen, in der geprüft wird, ob die Datei vorhanden ist.
Dann kannst Du das Skript auch mit /bin/sh (das ist die dash ) ausführen lassen. Die braucht etwas weniger Resourcen als die bash , obwohl das in diesem Fall vermutlich kaum auffallen wird.
Das mit dem frühen Abbruch ist ebenfalls sehr gut.
Das entspricht auch dem üblichen Muster bei der Programmierung, erst mal die Eingangswerte auf Gültigkeit zu prüfen und im Fehlerfalle abzubrechen. Dann hat man den Code schön sauber getrennt von der eigentlichen Verarbeitung. Dabei fällt mir auf: In dem Sinne sollte man auch die Existenz des Verzeichnisses in Parameter 1 prüfen, weil sonst ggf. durch den mkdir -p auch dieses Verzeichnis angelegt wird. Das ist aber nicht im Sinne des Erfinders und man braucht dann auch gar nicht anzufangen etwas zu tun, weil dort dann sowieso keine Dateien liegen. Also könnte man noch so etwas in Zeile 5 einfügen: | if [ ! -d "$1" ]; then
echo "ERROR: directory does not exist: $1" >&2
exit 2
fi
|
Danke dafür, wird morgen gleich getestet.
Bitte! Ciao robert
|
BlackBoxCoder
(Themenstarter)
Anmeldungsdatum: 19. Juni 2013
Beiträge: 22
|
Guten Morgen liebe Community, ich habe die Vorschläge von Robert direkt mal implementiert. Mit der dash-Variante funktioniert das Script (Zumindest auf meinem Herzkranken-Netbook) um einiges schneller.
Die Exceptions habe ich auch eingefügt. So damit ich es anderen Anwendern leichter machen kann, sollten sie das gleiche oder ein ähnliches Problem haben, füge ich hier auch noch den finalen Code ein. Robert: ich würde das Script gerne in meinem Blog zur Verfügung, darf/soll ich dich in den Credits im Script erwähnen? Vielen Vielen Dank für die gesamte Hilfe ☺ Gruß,
BBC (Chris) Nachtrag 08.01.2015 08:54: bin/sh funktioniert in dem Script nicht. Da wir hier noch den Befehl converting haben.
Also wird doch bin/bash benötigt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | #!/bin/bash
##################Handling exceptions################
if [ $# -lt 3 ]; then
echo "ERROR: need three arguments." >&2
exit 1
fi
if [ ! -d "$1" ]; then
echo "ERROR: directory does not exist: $1" >&2
exit 2
fi
#####################################################
target="$1/thumb"
mkdir -p "$target" #create dir thumb if not exits
for i in $1/*.{jpg,jpeg,bmp,png}; #for each jpg,jpeg,bmp,png in the dir do
do
if [ -f "$i" ]; then
base="${i##*/}" #get just the filename
convert "$1/$base" -resize "$2x$3" "$target/$base"
fi
done
echo "converting done!"
|
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13217
|
BlackBoxCoder schrieb:
Mit der dash-Variante funktioniert das Script (Zumindest auf meinem Herzkranken-Netbook) um einiges schneller.
Wie viel macht das denn aus?
So damit ich es anderen Anwendern leichter machen kann, sollten sie das gleiche oder ein ähnliches Problem haben, füge ich hier auch noch den finalen Code ein.
Fein.
Robert: ich würde das Script gerne in meinem Blog zur Verfügung, darf/soll ich dich in den Credits im Script erwähnen?
Ja, gerne.
Vielen Vielen Dank für die gesamte Hilfe ☺
Gerne.
bin/sh funktioniert in dem Script nicht. Da wir hier noch den Befehl converting haben.
Du brauchst "/bin/sh". In dem Skript gibt es keinen Befehl converting . Was ist der Fehler?
Also wird doch bin/bash benötigt.
Das glaube ich nicht.
|
BlackBoxCoder
(Themenstarter)
Anmeldungsdatum: 19. Juni 2013
Beiträge: 22
|
Hey, eigentlich meinte ich diesen Befehl: convert "$1/$base" -resize "$2x$3" "$target/$base" Dieser wird meiner Meinung nach erst gar nicht ausgeführt wenn ich bin/sh statt bin/bash nehme. (ich hatte es ja erst drin, aber nach meinem Nachtrag wieder getauscht 😉 ) Da der Befehl nicht ausgeführt wird, geht es um den Faktor 2-3 schneller (aktuell liegen in dem Ordner 4 Bilder). Lediglich der Ordner "thumb" wird erstellt. Gruß,
BBC
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13217
|
BlackBoxCoder schrieb:
convert "$1/$base" -resize "$2x$3" "$target/$base"
Das ist aber ein externer Befehl, wird also nicht von der Shell selbst ausgeführt. Dann kann es nur an irgendwelchen Einstellungen liegen (z.B. $PATH). Oder hast Du vielleicht einen Alias definiert?
Dieser wird meiner Meinung nach erst gar nicht ausgeführt wenn ich bin/sh statt bin/bash nehme. (ich hatte es ja erst drin, aber nach meinem Nachtrag wieder getauscht 😉 )
Dann führ mal das Skript so aus /bin/sh -x script-name verzeichnix x y . Die Debug-Ausgabe gibt dann ggf. einen Hinweis, was da los ist. Zusätzlich kannst Du mal auf dem Shell-Prompt folgendes eingeben: type -a convert . Dann siehst Du, wie die interaktive Shell das auflöst. Kannst Du natürlich auch oben im Skript einbauen.
Da der Befehl nicht ausgeführt wird, geht es um den Faktor 2-3 schneller (aktuell liegen in dem Ordner 4 Bilder).
Logisch, aber diese Art von Unterschied ist natürlich nicht gemeint.
Lediglich der Ordner "thumb" wird erstellt.
Sehr seltsam.
|