Schrittweise

Vom Shell-Skript zum kompakten Powertool

Manchmal muss es schnell gehen: Liefert die Suche nach einem bestimmten Tool keine befriedigenden Ergebnisse, zimmert sich der kundige Linux-Anwender mit wenigen Zeilen Shell-Code eine eigene Lösung zusammen. Mit der Zeit wachsen dann die Anforderungen, aus dem schnell entworfenen Skript entsteht schließlich ein robustes Programm. Dazu gibt es bestimmte Strickmuster, die wir im Folgenden vorstellen wollen. Als Beispiel dazu entsteht ein Screenshot-Werkzeug, das es ermöglicht, den kompletten Bildschirminhalt oder Teile davon zu erfassen, als Grafik abzuspeichern oder an andere Programm durchzureichen.

Die Basis zu unserem kleinen Projekt liefert das Tool Import [1] aus der leistungsfähigen Kommandozeilen-Grafiksuite ImageMagick [2]. Ein Blick in die Import-Manpage verrät, was dieses Werkzeug alles kann: Es erfasst auf Wunsch ein einzelnes Fenster, den ganzen Desktop oder nur einen markierten Bereich. Die Grafiken legt es entweder in einer Datei ab oder gibt sie auf die Standardausgabe aus, von wo aus Sie die Daten bei Bedarf mithilfe einer Pipe an einen anderen Befehl weitergeben. Führen Sie den Befehl import abc.jpg auf der Kommandozeile aus, so verwandelt sich der Mauszeiger in ein Fadenkreuz, mit dem Sie dann die Auswahl treffen. Lassen Sie die Maustaste los, knipst das Tool den Screenshot und speichert ihn in der Datei namens abc.jpg ab.

TIPP

ImageMagick kann mit über 100 Grafikformaten umgehen. Verwenden Sie für den Dateinamen eine Endung wie tiff, gif oder png, dann wählt die Software automatisch das richtige Format.

Viele in Desktops integrierte Screenshot-Tools beherrschen nur wenige Formate, etwa JPG oder PNG. Einige erlauben zudem kein Erfassen eines definierten Bereichs, wie eines Bildausschnitts oder Fensters. Zudem fallen oft zwei bis drei Arbeitsschritte an, bis die gewünschte Datei als Grafik vorliegt. Dabei ließe sich alles in einem Rutsch erledigen: Einfach nur per Tastaturkürzel, Startmenü oder Symbol in der Task-Leiste das Tool starten, ein Fenster oder einen Bildausschnitt blitzschnell auswählen und dann gleich automatisiert abspeichern und eventuell an ein anderes Programm weiterreichen.

Im Eigenbau

Da mit Import ein sehr leistungsstarkes Kommandozeilentool für Screenshots bereitsteht, bietet es sich an, mit einem Shell-Skript die Lösung des Problems zu suchen (Listing 1). Dazu legen Sie sich am besten einen Ordner an, den Sie als Programm- oder Testordner benutzen.

Listing 1

#!/bin/bash
pfad=${HOME}/Programme/bildcutter
bilder=${HOME}/Bilder/Importe
declare -i nummer
nummer=$(cat ${pfad}/bildnummer)
import ${bilder}/${nummer}.jpg
let nummer++
echo $nummer > ${pfad}/bildnummer
@KE

Wie jedes ordentliche Skript beginnt diese Datei mit einer Zeile, die Auskunft über den zu verwendenden Interpreter gibt. Hinter dem Shebang (#!) steht der genaue Pfad zu diesem. Die Bash ist für solche Aufgaben immer eine gute Wahl. In den Zeilen 2 und 3 setzen Sie die Variablen für die verwendeten Pfade, unter anderem zu dem Ordner, in dem Sie Grafiken abspeichern wollen.

Um die automatische Vergabe eines Dateinamens zu ermöglichen, arbeiten Sie mit einer fortlaufenden Nummer, die Sie als Teil des Dateinamens verwenden. Die Anweisung in Zeile 4 legt eine Variable als Ganzzahl an, die Sie bei Bedarf hochzählen (Zeile 7). Während des weiteren Programmablaufs liest das Skript diese Zahl aus einer Datei aus (Zeile 5) oder schreibt die um den Wert Eins erhöhte Zahl wieder in diese hinein (Zeile 8).

Sie benötigen also für den ersten Start des Skripts eine Datei, in der eine Nummer steht. Statt umständlich einen Editor zu öffnen, erstellen Sie dieses File in einem Terminal mit dem Kommando: @LI: $ echo 1 > ${HOME}/Programme/bildcutter/bildnummer

In Zeile 5 lesen Sie diese Zahl mit einem einfachen Cat-Befehl aus. Da diese Anweisung in runden Klammern mit einem vorangestellten Dollar-Zeichen steht, führt die Bash das Kommando in einer Subshell aus und speichert die Ausgabe in der Variablen nummer ab. Nach dieser Operation erfolgt der eigentliche Import.

Statt eines Namens für die Bilddatei kombiniert das Skript den Pfad, den Sie in der Variablen bilder gespeichert haben, sowie die Nummer und ein angehängtes .jpg. Die geschweiften Klammern um die Namen der Variablen sorgen dafür, dass die Shell die darin abgespeicherten Werte einsetzt und so das Bild mit einer Nummer versehen im gewünschten Verzeichnis abspeichert. Durch den Befehl in Zeile 7 zählt das Skript die Variable nummer um eins hoch. Mittels eines einfachen Echo-Befehls in Zeile 8 schreibt es den neuen Wert in die Datei bildnummer.

Variationen

Sie dürfen auch andere Formate für das Bild verwenden, wenn Sie eine spezielle Aufgaben damit erledigen wollen. So könnten Sie etwa interessante Textpassagen ausschneiden und sie mittels Pipe an das Texterkennungsprogramm Ocrad [3] weitergeben, damit dieses dann die Bilddatei in eine Textdatei umwandelt. Dazu müssen Sie allerdings mit weniger bekannten Formaten wie PBM, PGM oder PPM arbeiten und das importierte Bild nicht abspeichern, sondern in die Standardausgabe schreiben.

Das Skript an sich lässt noch Komfort vermissen: Sie müssen es immer von der Kommandozeile aus aufrufen. Da bietet sich an, im Desktop ein Tastenkürzel zu erstellen, das einfach auf das Skript verweist (Abbildung 1). Gnome bietet diese Möglichkeit unter Systemeinstellungen | Tastatur | Tastenkürzel, bei KDE verwenden Sie Systemeinstellungen | Systemverwaltung | Tastenkombinationen. So gut wie alle grafischen Oberflächen bieten die Möglichkeit, solche Tastenkürzel anzulegen und zu konfigurieren.

Abbildung 1

Abbildung 1: Während Sie im Web surfen, sichern Sie per Druck auf einen Starter oder mithilfe eines Tastaturkürzels komfortabel einen Bildausschnitt.

Bei regelmäßiger Nutzung des kleinen Batch-Programms stellen Sie sicher schnell fest, dass es sich zwar fast wie ein vollwertiges Desktop-Tool verhält, aber trotzdem noch einige Kanten aufweist. Dann zahlt es sich aus, dass Sie die Möglichkeit haben, es unkompliziert nach Belieben zu erweitern.

Etwas robuster

Im nächsten Schritt geht es daran, das Skript so zu erweitern, dass es sich bei Bedarf einfach auf ein anderes System übertragen ließe. Bislang ist es ziemlich einfach aufgebaut und außerdem anfällig für Fehler. Listing 2 zeigt eine optimierte Version.

In Zeile 2 sehen Sie gleich die erste Erweiterung des Programms in Form der Übernahme eines Parameters. Falls Sie dem Skript einen Parameter übergeben, nimmt es mit $1 oder ${1} Bezug darauf. Damit Sie nicht zwingend einen Parameter anzuhängen brauchen, existiert mit der Erweiterung :-nichts beim Namen der Variable ein Fallback. Geben Sie nichts an, erhält diese den String nichtsals Wert. Das ist notwendig, um beim späteren Zugriff keine Fehlermeldung zu erhalten.

Listing 2

01 #!/bin/bash
02 GRPROGRAMM=${1:-nichts}
03 BILDER=~/Bilder
04 ZIEL=${BILDER}/Importe
05 BNR=$(date +"%Y-%m-%d_%H%M%S")
06 FMT=jpg
07 BILDNAME=ImportiertesBild-${BNR}.${FMT}
08 CONFIG=${HOME}/.config/sniprc
09 [ -f ${CONFIG} ] && source ${CONFIG}
10 [ -d ${ZIEL} ] ] || mkdir -p ${ZIEL}
11 import ${ZIEL}/${BILDNAME} && \
12 which ${GRPROGRAMM} &>/dev/null && \
13 ${GRPROGRAMM} ${ZIEL}/${BILDNAME}

In den Zeilen 3 bis 7 speichern Variablen – ausschließlich mit Großbuchstaben im Namen – Pfadangaben und Dateinamen. Der Einsatz der Großbuchstaben hilft, den Code übersichtlich zu gestalten. In der Regel ändern sich diese Variablen während des gesamten Verlaufs des Programms nicht mehr.

In Zeile 5 generiert das Kommando date einen eindeutigen und fortlaufenden Namensbestandteil für die Bilder. Der Format-String hinter dem Plus-Zeichen sorgt dafür, dass sich Jahr, Monat, Tag und die Uhrzeit auf die Sekunde genau im Namen wiederfinden. In Zeile 6 geben Sie das gewünschte Suffix für die Bilder an. Auf diese Weise bestimmen Sie den Dateityp. Zeile 7 baut den Namen für die Bilddateien zusammen.

Der zusammengesetzte Ausdruck in Zeile 4 markiert den Ort, an dem das Skript die Grafiken speichert. Da das Programm aber nicht weiß, ob dieser Ordner existiert, prüft es im späteren Verlauf, ob Sie das Verzeichnis angelegt haben. Ist das nicht der Fall, übernimmt es selbst diese Aufgabe.

Zeile 8 zeigt den Pfad zu einer Konfigurationsdatei für Anwender. Das Skript prüft in Zeile 9, ob diese vorliegt, und baut deren Zeilen ins Skript ein. So kann der Benutzer die vordefinierten Werte aus den Zeilen 3 bis 7 überschreiben, ohne dazu das Skript anzufassen oder zu kopieren.

Zeile 10 prüft, ob das Zielverzeichnis für die Bilder existiert – falls nicht, legt das Skript diese Verzeichnisse an. Der Parameter -p für das Kommando mkdir sorgt dafür, dass dabei alle notwendigen übergeordneten Verzeichnisse ebenfalls entstehen.

In Zeile 11 erfolgt der eigentliche Import. Der Befehl enthält keine Optionen. Hier böte sich nochmals Potenzial für eine Modifikation. War der Import erfolgreich, so kommen die nächsten Befehle nach der Und-Verkettung && zum Zuge – der Übersicht halber in zwei Zeilen aufgeteilt.

Beim Aufruf übergeben Sie dem Skript einen Parameter, wie den String gimp für das gleichnamige Bildbearbeitungsprogramm. Das Skript überprüft, ob es in den regulären Pfad eine ausführbare Datei gibt (Zeile 12). Dabei schreibt es die Ausgabe nach /dev/null, da nur der Rückgabewert interessant für den weiteren Verlauf des Programms ist. Ist die Suche erfolgreich, übergibt das Skript die Bilddatei an die entsprechende Applikation (Zeile 13).

Fazit

Es bleibt Ihnen überlassen, ob und welche Programme Sie dem Skript als Parameter übergeben. Fest steht, dass Sie mit dem kleinen Skript so manche vollwertige Desktop-Anwendung locker in die Tasche stecken. Dabei haben Sie aber noch den Vorteil, ohne großen Aufwand das Skript bei Bedarf nach Belieben zu erweitern und auf andere Systeme zu portieren.

Mögliche Erweiterungen bauen Sie ein, indem Sie zum Beispiel dem Import-Befehl ein paar Optionen mit auf den Weg geben. So erstellen Sie mit import -snaps 3 gleich ganze Sequenzen von Screenshots, wobei das Tool die Namen für die Bilddateien automatisch generiert. Die Manpage von Import gibt weitere Auskunft über die vielen verschiedenen Optionen. 

Infos

[1] Import: http://www.imagemagick.org/script/import.php

[2] ImageMagick: Thomas Drilling, "Zauberkasten", LU 08/2012, S. 68, http://www.linux-community.de/26395

[3] Ocrad: http://www.gnu.org/software/ocrad/

Tip a friend    Druckansicht beenden Bookmark and Share
Kommentare