ExcitedSpoon
Anmeldungsdatum: 17. Juli 2010
Beiträge: 226
Wohnort: /home/berlin
|
Hallo, in diesem Thread hatte ich folgenden Lösungsvorschlag gegeben:
Du könntest auch scrot verwenden. Das nummeriert zwar nicht durch, aber wenn man dort keinen Dateinamen angibt, dann benennt er die Datei nach der aktuellen Systemzeit:
mohmann@X220 /tmp/scrot % scrot
mohmann@X220 /tmp/scrot % ls
2012-03-01-131219_1920x1200_scrot.png
Das lässt sich dann auch prima chronologisch sortieren. EDIT: Wenn es wirklich kein Programm gibt, was deine Anforderungen erfüllt, dann bliebt immernoch die Möglichkeit sich nen Wrapper für scrot oder ein ähnliches CLI-Tool zu schreiben, welcher sich beim Screenshot die aktuelle LfdNr. aus einer Datei oder Variablen zieht, daraus den Dateinamen bildet, die LfdNr. inkrementiert und sie wieder abspeichert.
Ich habe das im letzten Abschnitt angesprochene Skript jetzt interessehalber mal in 10min quick&dirty selber geschrieben. ⇒ Funktionierte gut. Habe danach mal versucht das ganze als wrapper für scrot zu schreiben (nscrot), der sich in allen Belangen so verahlten soll wie scrot, ausser: a) -h|--help geben anstatt der scrot-help die "eigene" Hilfe aus, b) -v|--version geben anstatt der scrot-version die "eigene" Version aus, c) ein nach den Optionen angefügter Dateiname (zb. 'nscrot -d 1 -c DATEINAME) führt zu einer Ausgabe der Usage (siehe Code), da 'nscrot' keinen Dateinamen erwartet, sondern ihn inkrementell erstellt.
Der unten angegebene Code funktionierte in meinen Tests genauso wie scrot auch ohne den wrapper funktionieren würde; ausser natürlich der gewollten Durchnummerierung der Screenshots (die scrot "bugs" mit inbegriffen, zb.: scrot -d -c produziert einen screenshot ohne Fehlermeldung, obwohl -d einen integer erwartet). Meine Frage jetzt: was ist die effektivste Methode um mit einem Shellscript einen Wrapper zu realisieren? Ich finde den Code so wie er ist irgendwie noch zu umständlich, da muss doch noch was zu vereinfachen sein, oder? Bin selbst nicht der beste "Shell-Progammierer", von daher bitte soviel Kritik wie nur möglich 😉. Im oberen Teil (<CONFIG>) kann man momentan 3 kleine Einstellungen vornehmen (kann natürlich auch noch in eine seperate Datei ausgelagert werden; für jetzt bleibts erstmal dort) nscrot (numbered scrot) 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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94 | #!/bin/bash
# nscrot version
nscrot_version="0.1"
# --- <CONFIG> ---
screenshot_prefix="screenshot-" # präfix des dateinames
screenshot_extension=".png" # dateiendung
screenshot_id_file=~/.nscrot-id # absoluter(!) pfad der datei, in die aktuelle ID gespeichert wird
# --- </CONFIG> ---
# ID laden
screenshot_id=`cat $screenshot_id_file 2>/dev/null`
# wenn datei leer, nicht existent oder inhalt kein integer, dann ID auf 0 setzen
[ "$screenshot_id" -ge 0 -o "$screenshot_id" -lt 0 2>/dev/null ] || screenshot_id=0
# filename zusammensetzen
screenshot_filename=$screenshot_prefix$screenshot_id$screenshot_extension
scrot_args=""
scrot_args_valid=0
do_scrot() {
# screenshot mit args und filename
scrot $1 $screenshot_filename
# ID inkrementieren
let "screenshot_id += 1"
# ID-File mit neuem wert anlegen/überschreiben
echo $screenshot_id > $screenshot_id_file
}
print_help() {
echo "nscrot is a scrot wrapper which creates consecutively numbered screenshots using scrot."
echo "Each screenshot is saved in the current working directory."
echo "Any custom filenames --contrary to 'regular' scrot-- are ignored."
echo
echo "For further help see 'man scrot'"
exit 0
}
print_version() {
echo "nscrot version "$nscrot_version
exit 0
}
print_usage() {
echo "Don't do that! See '$0 --help' for help."
exit 0
}
set -- `getopt -n$0 -u -a --longoptions="help version border count multidisp select unfocused silent delay: exec: quality: thumb:" "h v b c m s u z d: e: q: t:" "$@"`
while [ $# -gt 0 ]
do
case "$1" in
-h|--help)
[ $# -eq 2 ] && print_help
;;
-v|--version)
[ $# -eq 2 ] && print_version
;;
-b|--border|-c|--count|-m|--multidisp|-s|--select|-u|--unfocused|-z|--silent)
scrot_args=$scrot_args" "$1
scrot_args_valid=1
;;
-d|--delay|-e|--exec|-q|--quality|-t|--thumb)
scrot_args=$scrot_args" "$1" "$2
scrot_args_valid=1
shift
;;
--)
# '--' ist der "separator" zwischen den angegebenen (gültigen)
# argumenten und dem evtl. zusätzlich angegebenen filename (welcher
# ignoriert werden soll)
#
# keine args => 'scrot'
[ $# -eq 1 ] && scrot_args_valid=1
;;
*)
# 'nscrot [filename]' abfangen (siehe eins drüber)
print_usage
break
;;
esac
shift
done
# screenshot nur mit validen (von scrot "geduldeten") args machen
[ "$scrot_args_valid" -gt 0 ] && do_scrot "$scrot_args"
|
Gruß Martin
|
senden9
Anmeldungsdatum: 8. Februar 2010
Beiträge: 965
Wohnort: Österreich
|
Alternative: Versuch mal "Shutter" das nummeriert die Screenshots von Haus aus durch.
|
ExcitedSpoon
(Themenstarter)
Anmeldungsdatum: 17. Juli 2010
Beiträge: 226
Wohnort: /home/berlin
|
senden9 schrieb: Alternative: Versuch mal "Shutter" das nummeriert die Screenshots von Haus aus durch.
Sag das mal dem OP aus dem verlinkten Thread 😉. Mir gehts hierbei eigentlich eher um den Lerneffekt. EDIT: ich mache meine Screenshots immer mit scrot, weil ichs so gewohnt bin. Mein "Tool" wäre lediglich ein kleines Gimmick, was ich ab und zu nutzen würde. Grüße
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Wenn man in einem Script, in dem es um Screenshots geht, jede 2. Variable mit "screenshot_" präfixt, dann beeinträchtigt das die Lesbarkeit enorm, denn gerade am Wortanfang wünscht man sich Signifikanz, welche das Gegenteil von Redundanz ist. Der Anfang sieht dann so aus:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | prefix="screenshot"
ext="png"
id_file=~/.nscrot-id
# ID lesen
id=$(cat $id_file 2>/dev/null)
# wenn datei leer, nicht existent oder inhalt kein integer, dann ID auf 0 setzen
[ "$id" -ge 0 -o "$id" -lt 0 2>/dev/null ] || id=0
filename=$prefix-$id.$ext
scrot_args=""
scrot_args_valid=0
do_scrot() {
scrot $1 $filename
let id+=1
echo $id > $id_file
}
|
Trivialitäten kommentiert man auch nicht, sondern Sachen, die nicht gleich ersichtlich sind. Ohne Leerstellen braucht let id+=1 auch keine Anführungsstriche, Backticks werden auch umso beliebter, je veralteter sie sind. Ich kenne scrot nicht, aber bei Bildschirmschonern hätte ich gleich 2-3 Ideen: a) Je nach dem wozu man sie verwenden will, möchte man denen vielleicht lieber einen Namen geben, mit dem man auch was anfangen kann, wie "Gedit-Bug" oder "vlc-artefakt". Dazu würde man den User mit read oder zenity auffordern einen Namen zu vergeben. Wenn der schon existiert könnte man erneut fragen. b) Da man selten mehr als 1 Screenshot pro Sekunde macht könnte man, wenn es auf einen sprechenden Namen nicht ankommt, einen Zeitstempel nehmen. c) Man könnte auch, statt die Nummer in einer Datei zu speichern, die gelöscht werden kann, die höchste Zahl ermitteln, die präfix-id.ext entspricht, und da eins draufzählen, oder gar Lücken füllen.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12822
|
ExcitedSpoon schrieb: Hallo, in diesem Thread hatte ich folgenden Lösungsvorschlag gegeben:
Du könntest auch scrot verwenden. Das nummeriert zwar nicht durch, aber wenn man dort keinen Dateinamen angibt, dann benennt er die Datei nach der aktuellen Systemzeit:
mohmann@X220 /tmp/scrot % scrot
mohmann@X220 /tmp/scrot % ls
2012-03-01-131219_1920x1200_scrot.png
Das lässt sich dann auch prima chronologisch sortieren. EDIT: Wenn es wirklich kein Programm gibt, was deine Anforderungen erfüllt, dann bliebt immernoch die Möglichkeit sich nen Wrapper für scrot oder ein ähnliches CLI-Tool zu schreiben, welcher sich beim Screenshot die aktuelle LfdNr. aus einer Datei oder Variablen zieht, daraus den Dateinamen bildet, die LfdNr. inkrementiert und sie wieder abspeichert.
Ich habe das im letzten Abschnitt angesprochene Skript jetzt interessehalber mal in 10min quick&dirty selber geschrieben. ⇒ Funktionierte gut. Habe danach mal versucht das ganze als wrapper für scrot zu schreiben (nscrot), der sich in allen Belangen so verahlten soll wie scrot, ausser: a) -h|--help geben anstatt der scrot-help die "eigene" Hilfe aus, b) -v|--version geben anstatt der scrot-version die "eigene" Version aus, c) ein nach den Optionen angefügter Dateiname (zb. 'nscrot -d 1 -c DATEINAME) führt zu einer Ausgabe der Usage (siehe Code), da 'nscrot' keinen Dateinamen erwartet, sondern ihn inkrementell erstellt.
Der unten angegebene Code funktionierte in meinen Tests genauso wie scrot auch ohne den wrapper funktionieren würde; ausser natürlich der gewollten Durchnummerierung der Screenshots (die scrot "bugs" mit inbegriffen, zb.: scrot -d -c produziert einen screenshot ohne Fehlermeldung, obwohl -d einen integer erwartet). Meine Frage jetzt: was ist die effektivste Methode um mit einem Shellscript einen Wrapper zu realisieren?
Mit der bash , die Arrays kennt, würde ich das ungefähr so machen: 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
28 | #!/bin/bash
# wrap a command by passing on all options
# which are not known by the wrapper
args=()
while [ $# -gt 0 ]; do
case "$1" in
-h|--help)
echo 'Help!'
exit 0
;;
# further wrapper options here
--) # end of option processing
shift
break
;;
*) # collect process args
args=("${args[@]}" "$1")
;;
esac
shift
done
echo 'preparation...'
exec ls "${args[@]}" "$@"
|
Das Vorgehen ist folgendermaßen: Bearbeite Argumente des Wrapper-Skripts sofort. Sammle alle Argumente für den anderen Prozess in einem Array (hier: "args"). Zusätzlich nutze "–" als Abbruchkriterium (sehr üblich, das macht die Shell selber auch), so dass alles danach unbearbeitet an den anderen Prozess weiter gegeben wird.
Ich finde den Code so wie er ist irgendwie noch zu umständlich, da muss doch noch was zu vereinfachen sein, oder? Bin selbst nicht der beste "Shell-Progammierer", von daher bitte soviel Kritik wie nur möglich 😉.
Sieht eigentlich schon ganz gut aus. Ich würde allerdings die exit -Aufrufe nicht im Skript und in Funktionen verteilen, sondern sie auf "main"-Ebene lassen. Also z.B. | print_version() {
echo "nscrot version "$nscrot_version
}
...
-v|--version)
[ $# -eq 2 ] && { print_version; exit; }
;;
|
M.E. ist die Struktur dann leichter zu lesen. Ciao robert
|
ExcitedSpoon
(Themenstarter)
Anmeldungsdatum: 17. Juli 2010
Beiträge: 226
Wohnort: /home/berlin
|
user unknown schrieb: Wenn man in einem Script, in dem es um Screenshots geht, jede 2. Variable mit "screenshot_" präfixt, dann beeinträchtigt das die Lesbarkeit enorm, denn gerade am Wortanfang wünscht man sich Signifikanz, welche das Gegenteil von Redundanz ist. [...]
Danke für die Kritik, aber du hast dir den vor mir verlinkten Post anscheinend nicht durchgelesen 😉.
Das mit den überlangen Präfixen sehe ich ein, das ist irgendwie ne macke von mir 😉. Ich fasse mal kurz zusammen: OP aus dem anderen Thread wollte, dass seine Screenshots, egal in welchem Ordner sie gespeichert werden, eine laufende Nummer erhalten, sprich: pwd=~/Desktop → Screenshot → bild-1.png, pwd=~/Pictures → Screenshot → bild-2.png. Er will, egal wo und wann er einen Screenshot macht, eine neue LfdNr haben. Es war eigentlich das Ziel des Skripts diese "Verhalten" umzusetzen 😉.
Trivialitäten kommentiert man auch nicht, sondern Sachen, die nicht gleich ersichtlich sind.
ich hatte das ursprünglich für den OP aus dem anderen Thread kommentier, mich dann aber doch entschieden das Skript hier zu posten.
a) Je nach dem wozu man sie verwenden will, möchte man denen vielleicht lieber einen Namen geben, mit dem man auch was anfangen kann, wie "Gedit-Bug" oder "vlc-artefakt". Dazu würde man den User mit read oder zenity auffordern einen Namen zu vergeben. Wenn der schon existiert könnte man erneut fragen.
das verstehe ich nicht, wie meinst du das? @rkim Sieht eigentlich schon ganz gut aus. Ich würde allerdings die exit-Aufrufe nicht im Skript und in Funktionen verteilen, sondern sie auf "main"-Ebene lassen.
Dass ich die exit-statement in funktionen verpackt habe ändert aber nix an der performanz des "programms", sondern dient in deiner variante lediglich der Lesbarkeit, richtig? (Im Endeffekt find ich die exit-statements in den funktionen auch blöd; ich müsste bei der wiederverwendung jedesmal dran denken, dass diese funktion de facto das programm beendet) Viele Grüße
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12822
|
ExcitedSpoon schrieb: user unknown schrieb: a) Je nach dem wozu man sie verwenden will, möchte man denen vielleicht lieber einen Namen geben, mit dem man auch was anfangen kann, wie "Gedit-Bug" oder "vlc-artefakt". Dazu würde man den User mit read oder zenity auffordern einen Namen zu vergeben. Wenn der schon existiert könnte man erneut fragen.
das verstehe ich nicht, wie meinst du das?
Ich verstehe uu so, dass er anregt eine Eingabemöglichkeit für den Dateinamen des Screenshots vorzusehen, denn ein sprechender Name hilft ungemein. Zusätzlich würde ich die Mimik mit der Id weglassen. Das ist unnötig kompliziert und außerdem musst Du mit der Id-Datei eigentlich auch sicherstellen, dass nicht zwei Prozesse gleichzeitig drauf zugreifen können usw. Man kann stattdessen sehr schöne Dinge mit date machen: 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
28
29
30
31 | 10:19:59 ~$ date '+%Y'
2012
10:20:02 ~$ date '+%Y%m'
201203
10:20:08 ~$ date '+%Y%m%d'
20120302
10:20:12 ~$ date '+%Y%m%d-%H%M%S'
20120302-102042
10:20:42 ~$ date '+%Y%m%d-%H%M%S'
20120302-102045
10:21:55 ~$ date '+%Y%m%d-%H%M%S'
20120302-102200
10:22:00 ~$ date -u '+%Y%m%d-%H%M%S'
20120302-092202
10:22:02 ~$ date '+%Y%m%d%H%M%S'
20120302102237
10:22:37 ~$ date -u '+%Y%m%d%H%M%S'
20120302092240
10:22:40 ~$ date -u '+%Y%m%d%H%M%S.%N'
20120302092404.231791700
10:24:33 ~$ for i in {1..10}; do date -u '+%Y%m%d%H%M%S.%3N'; done
20120302092445.852
20120302092445.881
20120302092445.911
20120302092445.936
20120302092445.962
20120302092445.987
20120302092446.013
20120302092446.039
20120302092446.064
20120302092446.090
|
Das schöne ist, man kann sogar danach sortieren und erhält eine chronologische Reihenfolge.
@rkim
s/i/l/
Sieht eigentlich schon ganz gut aus. Ich würde allerdings die exit-Aufrufe nicht im Skript und in Funktionen verteilen, sondern sie auf "main"-Ebene lassen.
Dass ich die exit-statement in funktionen verpackt habe ändert aber nix an der performanz des "programms", sondern dient in deiner variante lediglich der Lesbarkeit, richtig? (Im Endeffekt find ich die exit-statements in den funktionen auch blöd; ich müsste bei der wiederverwendung jedesmal dran denken, dass diese funktion de facto das programm beendet)
Genau das meinte ich. Theoretisch ist auch die Modularität der Funktionen höher, da Du sie in mehr Situationen benutzen kannst, wenn sie nicht immer gleich den Prozess beenden. Praktisch macht das aber in diesem Fall keinen nennenswerten Unterschied, da Du sie sowieso nur an einer Stelle aufrufen willst. Ciao robert
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
ExcitedSpoon schrieb: a) Je nach dem wozu man sie verwenden will, möchte man denen vielleicht lieber einen Namen geben, mit dem man auch was anfangen kann, wie "Gedit-Bug" oder "vlc-artefakt". Dazu würde man den User mit read oder zenity auffordern einen Namen zu vergeben. Wenn der schon existiert könnte man erneut fragen.
das verstehe ich nicht, wie meinst du das?
Wenn es für jmd. anderen mit fixen Anforderungen ist, dann macht es wenig Sinn mit Dir zu diskutieren, ob Namen, die den Screenshot beschreiben, nicht sinnvoller sind.
Danke für die Kritik, aber du hast dir den vor mir verlinkten Post anscheinend nicht durchgelesen 😉.
Richtig, und rklm offenbar auch nicht. ☺ rklm schrieb: Das ist unnötig kompliziert und außerdem musst Du mit der Id-Datei eigentlich auch sicherstellen, dass nicht zwei Prozesse gleichzeitig drauf zugreifen können usw.
Und meinen offenbar auch nicht. ☺ | date -u '+%Y%m%d%H%M%S'
20120302092240
|
Das kann man ja nicht lesen!
| date -u '+%Y-%m-%d_%H:%M:%S'
2012-03-02_12:00:20
|
kann man auch numerisch sortieren, aber lesen kann man es zudem. ☺ Aber scrot macht das schon selbst. ☺
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12822
|
user unknown schrieb: ExcitedSpoon schrieb: Danke für die Kritik, aber du hast dir den vor mir verlinkten Post anscheinend nicht durchgelesen 😉.
Hätte man das müssen? Ich habe den Thread so verstanden, dass Du extra einen neuen Thread für ein ganz anderes Thema aufgemacht hat, das von dem anderen Thread nur inspiriert war. In diesem Thread geht es doch hauptsächlich darum, einen Wrapper zu schreiben (siehe Thema).
rklm schrieb: Das ist unnötig kompliziert und außerdem musst Du mit der Id-Datei eigentlich auch sicherstellen, dass nicht zwei Prozesse gleichzeitig drauf zugreifen können usw.
Und meinen offenbar auch nicht. ☺
Doch, aber Zeitstempel sind nicht der Punkt (s.u.).
| date -u '+%Y%m%d%H%M%S'
20120302092240
|
Das kann man ja nicht lesen!
Muss man ja auch nicht. Es ging lediglich um ein Verfahren eindeutige Ids zu generieren, nicht in erster Linie darum, Zeitstempel sichtbar zu machen. Das war ein Vorschlag um die Id-Mimik zu ersetzen, die im ersten Posting verwendet wurde. Bis neulich robert
|