[[Vorlage(Getestet, focal, bionic, )]] {{{#!vorlage Wissen [:Pakete_installieren: Installation von Programmen] [:Editor: Einen Editor öffnen] [:Rechte: Rechte für Dateien und Ordner ändern] [:Autostart: Programme automatisch starten] (optional) }}} [[Inhaltsverzeichnis(1)]] [[Bild(Wiki/Icons/terminal.png, 48, align=left)]] Wer [:Shell:]-Skripte schreibt und nutzt, möchte Rückmeldungen oder Fragen unter Umständen mit grafischen Elementen kombinieren. Benutzerabfragen in einem eigenen Dialog anzuzeigen wäre da ein erster Schritt. Für [:GTK:]-Dialoge gibt es dafür das Programm [gnomeprojects:Zenity:] {en}. Für [:KDE:] bzw. [:Qt:]-Dialoge gibt es das Programm [:KDialog:] mit ähnlicher Funktionalität. Die Abspaltung (Fork) [:yad:] bietet dagegen erweiterte Möglichkeiten bei Darstellung und Benutzerinteraktion. = Installation = Zuerst muss folgendes Paket installiert [1] werden: {{{#!vorlage Paketinstallation zenity }}} = Beispielskript = Anhand eines kleines Skriptes sollen die Möglichkeiten des Programms aufgezeigt werden. Das Beispielskript ist recht simpel aufgebaut: Es soll zuerst eine Warnung zum Programm angezeigt werden, dann wird vom Benutzer eine Texteingabe und eine Passworteingabe gefordert und alles am Ende wieder angezeigt. Die Quellcodezeilen sind nummeriert, um sie später besser erklären zu können. == Allgemeine Informationen == Zuvor ein paar allgemeine Informationen zur Shell-Programmierung: In der Regel reicht es in der ersten Zeile die Standardshell unter '''/bin/sh''' zu benutzen. Die if-then-Konstrukte werden benutzt, um festzustellen, ob der Benutzer auf ''"Abbrechen"'' bzw. ''"Nein"'' geklickt hat. Der Befehl "exit" beendet in so einem Fall das Skript. Ein "\n" in einer Textzeile sorgt für einen Zeilenumbruch. Die Variablenzuweisung mit "=" kann später per "$" wieder ausgelesen werden. Damit die Skripte starten, muss man diese nach dem Speichern ausführbar machen [3]. == Quellcode == Folgendes Skript gibt man (ohne Zeilennummern) in einem Editor [2] ein und speichert es an einen beliebigen Ort: {{{#!code bash #!/bin/bash -e exec 2>/dev/null # vernichtet nervige Fehlermeldungen if ! zenity --warning --text "Dieses Programm ist eigentlich harmlos\!\nTrotzdem fortfahren?"; then exit; fi if ! NAME=$(zenity --entry --text "Bitte geben Sie Ihren Namen ein:" --title "Wer sind Sie?"); then exit; fi if ! PASS=$(zenity --entry --hide-text --text "Bitte geben Sie das Passwort ein:" --title "Und das Passwort?"); then exit; fi ( echo "25"; sleep 1 echo "# Statusmeldung 1" echo "50"; sleep 1 echo "# Statusmeldung 2" echo "100" ) | zenity --progress --text "Vorgang wird bearbeitet" --percentage=0 zenity --info --text "Ihr Name: $NAME\nIhr Passwort: $PASS" --title "Das Ergebnis!" }}} == Erläuterungen == * '''Zeile 2:''' Diese Zeile ist optional und führt zur Vernichtung von zwar harmlosen, aber nervigen Fehlermeldungen. Siehe: [#Probleme-und-Loesungen Probleme und Lösungen] * '''Zeile 3:''' Die Option `--warning` zeigt eine Warnung mit den Optionen ''"Ok"'' und ''"Abbrechen"'' an. Den angezeigten Text kann man immer mit der Option `--text` beeinflussen. Bei neueren Versionen bekommt man jedoch nur noch eine Warnung angezeigt. Dort muss die Option `--question` für einen Fragedialog genutzt werden. * '''Zeile 7''' - Die Option ''--entry'' zeigt ein Texteingabefeld mit den Optionen ''"Ok"'' und ''"Abbrechen"'' an. * '''Zeile 11:''' - Dies zeigt wieder ein Texteingabefeld, die Option `--hide-text` verschlüsselt dabei aber die Eingabe durch Sternchen. * '''Zeilen 15-21''' - Es wird ein Fortschrittsbalken mit dem Startwert 0% angezeigt, dessen Prozentzahl wird in 25er Schritten hochgezählt und der Anzeigetext ''"Statusmeldung X"'' bei jedem Schritt verändert. * '''Zeile 23''' - Am Ende wird per `--info` ein Informationsfenster mit den eingegebenen Daten angezeigt. = Weitere Optionen = [[Bild(./zenity.png, align=right)]] [[Bild(./zenity1.png, align=right)]] {{{#!vorlage Tabelle Option '''Aktion''' +++ `--info` Information +++ `--warning` Warnung +++ `--error` Fehler +++ `--question` Frage +++ `--notification` Benachrichtungsfeld +++ `--entry` Texteingabe +++ `--file-selection` Dateiauswahl +++ `--list` Listenauswahl +++ `--progress` Fortschrittsanzeige +++ `--scale` Schieberegler +++ `--password` Passwort +++ `--entry --hide-text` Texteingabe mit verstecktem Text +++ `--calendar` Kalender }}} Dies ist natürlich nur ein Teil von dem, was Zenity kann. Genaueres erfährt man im Terminal per {{{#!vorlage Befehl zenity --help }}} oder in der [:man:Manpage] zu Zenity. = Programmumschalter = Öfters möchte man mit einem simplen Skript zwei gegenteilige Aktionen ausführen, z.B. ein Programm starten und beenden oder sich ins Internet ein- und wieder auswählen. Eine Lösungsmöglichkeit wären zwei getrennte Skripte, die das erledigen. Aus Platzgründen wäre es aber komfortabler, dies mit einem einzigen Icon (welches sich je nach Status verändert) im Panel zu erreichen. {{{#!vorlage Hinweis Der Befehl `zenity --notify` erzeugt mit aktuellen Versionen von zenity keine Panel-Icons mehr, sondern Benachrichtigungen, deren Verhalten von der Arbeitsumgebung abhängig ist. Der Programmumschalter funktioniert daher nicht unter allen Desktopumgebungen. }}} == Grundgerüst erstellen == Das Skript wird in einem Editor [2] erstellt. Hier fügt man das Grundgerüst ein: {{{#!code bash #!/bin/bash while true do zenity --notification --window-icon=$HOME/.icons/status1.png # Befehl 1 zenity --notification --window-icon=$HOME/.icons/status2.png # Befehl 2 done }}} Danach muss das Skript ausführbar gemacht werden [3]. === Erklärung === Das Skript ist eine Endlosschleife, die zwischen zwei Modi hin- und herschaltet. Zuerst wird zenity aufgerufen und präsentiert im Benachrichtigungsfeld des Panels das Symbol '''status1.png'''. Klickt man auf dieses, wird `Befehl 1` ausgeführt und sofort wieder zenity gestartet, dieses mal aber mit '''status2.png''' als Bild. Klickt man wieder darauf, wird `Befehl 2` abgearbeitet und die Schleife fängt von vorne an. Dies stellt einen simplen Umschalter dar. == Befehle einfügen == Anstelle der beiden Kommentare muss man die Befehle (es sind natürlich auch mehrere Zeilen möglich) einfügen, die abgearbeitet werden sollen. == Symbole wählen == Symbole werden im versteckten Ordner '''~/.icons''' im [:Homeverzeichnis:] gespeichert. Die Wahl ist dabei willkürlich und kann nach Belieben geändert werden. Manchmal existiert dieser Ordner bereits, ansonsten legt man ihn neu an. Sinnvolle Symbole sind z.B. simple rote und grüne Schaltflächen: [[Bild(./status_off.png)]] [[Bild(./status_on.png)]] == Autostart == Die fertige Datei kann man dann bei der Anmeldung automatisch ausführen lassen [4]. == Beispiele == [[Anker(DSL)]] === Internet-Einwahl === Eine sehr gute Anwendung findet man, wenn man sich ins Internet einwählen möchte. Nicht jeder Benutzer möchte DSL sofort beim PC-Start laufen lassen, für ISDN-Benutzer kommt dies sowieso nicht in Frage. Voraussetzung ist, dass die Internetverbindung mit `pppoeconf` eingerichtet wurde und die automatische Einwahl nicht aktiviert ist. Der Provider heißt hier `dsl-provider` und muss ggf. angepasst werden. Als Symbole kann man die zwei Netzwerk-Bilder aus Ubuntu nehmen: [[Bild(./dsl_stat_off.png, 20)]] [[Bild(./dsl_stat_on.png, 20)]] Nach dem Speichern beider Bilder im '''.icons'''-Ordner lautet das Skript dann: {{{#!code bash #!/bin/bash while true do zenity --notification --window-icon=$HOME/.icons/dsl_stat_off.png pon dsl-provider zenity --notification --window-icon=$HOME/.icons/dsl_stat_on.png poff -a done }}} Dieses dann z.B. als '''dsl-dial.sh''' speichern, ausführbar machen und im Autostart eintragen. = Zenity als Abfrage für dd-Backup nutzen = Mit diesem kleinen Script lassen sich die notwendigen Eingaben für das Erstellen eines Partitonsimage abfragen. Es ist besonders für unerfahrene Benutzer brauchbar, da es nahezu selbsterklärend ist. {{{#!code bash #!/bin/bash zenity --info --text "Im folgenden Auswahlfenster das zu sichernde Laufwerk auswählen. Der Syntax lautet sdx.x" --title "Quelle" cd / && cd /dev && Quelle=$(zenity --file-selection) zenity --info --text "Jetzt den Ort ausgewählen, wohin das Image gespeichert werden soll" --title "Zielordner" cd / && Ziel=$(zenity --file-selection --directory .) zenity --info --text "Dateiname des Images festlegen. Das Image muss mit der Dateiendung .img (backup.img) gespeichert werden." --title "Imagename festlegen" Dateiname=$(zenity --entry --title "Dateiname" --text "Beispiel: backup-sda1.img") sudo dd if=$Quelle bs=1M of=$Ziel/$Dateiname & ddpid=$! ; while [ "$(ps -a | grep $ddpid)" ]; do sudo kill -SIGUSR1 $ddpid; sleep 5; done }}} Nachdem man das Skript auf dem Rechner gespeichert hat, z.B. als '''backups.sh''', muss man es noch ausführbar machen. = Grafische Passwort-Abfrage mit Zenity = [:Zenity:] bietet eine Möglichkeit, das [:sudo:]-Passwort grafisch zu erfragen. Hier wird das Passwort in eine Variable `PASSW` zwischen gespeichert und per Pipe an sudo übergeben. Im unteren Beispiel wird eine [:Samba:]-Freigabe per Skript gemountet. Hierbei ist zu beachten, dass das Passwort für sudo und für dem Samba-Login gleich sein muss. {{{#!code bash #! /bin/bash PASSW=$(zenity --entry --hide-text --text "Bitte Passwort eingeben:" --title "SMB/CIFS Passwort?") echo -e "$PASSW\n" | sudo -S -s -- mount -t cifs //meinServer/smbQuelle /mnt/smbZiel -o iocharset=utf8 -o user=derUsername -o pass=$PASSW PASSW="" sudo -k }}} = Fortschrittsanzeige = == Mit Statussymbol == Das Benachrichtigungsfeld kann auch über einen Dateideskriptor angesteuert werden. Damit Zenity auf Eingaben wartet, muss die Option ''--listen'' gesetzt werden. Dadurch kann man den Status einer länger dauernden Aktion, z.B. Herunter-/Hochladen von größeren Datenmengen oder das Konvertieren vieler Dateien, fortlaufend aktualisieren. === Quellcode === Das Skript wird in einem Editor [2] erstellt. Hier fügt man das Grundgerüst ein: {{{#!code bash #!/bin/bash exec 3> >(zenity --notification --listen) for datei in "$1"/* do echo "tooltip:Aktionen für ${datei} werden durchgeführt" >&3 #Befehle für aktuelle Datei abarbeiten done echo "message:Vorgang abgeschlossen" >&3 exec 3>&- }}} === Erläuterungen === * '''Zeile 2:''' - Hier wird der Dateideskriptor `3` geöffnet und Zenity gestartet. Es kann auch ein anderer Dateideskriptor >=3 verwendet werden. * '''Zeilen 4-8:''' - Für alle Dateien im Verzeichnis `$1` werden die entsprechenden Befehle abgearbeitet. Zeile 7 muss durch die jeweiligen echten Befehle ersetzt werden. * '''Zeile 6:''' - Der Tooltip für das Symbol wird bei jedem Durchgang aktualisiert * '''Zeile 10:''' - unter dem Benachrichtigungssymbol wird eine Sprechblase angezeigt * '''Zeile 12:''' - Der Dateideskriptor wird geschlossen und Zenity beendet. === Kommandos === Das Benachrichtigungssymbol lässt sich über folgende Kommandos steuern. Das Format ist immer {{{ : }}} {{{#!vorlage Tabelle '''Option''' '''Aktion''' +++ `icon` Das anzuzeigende Icon. Als Wert gibt man den Pfad zum jeweiligen Icon an. +++ `visible` Soll ein Symbol angezeigt werden? Mögliche Werte sind `true` und `false` +++ `tooltip` Text des Tooltips +++ `message` Eine Sprechblase wird unterhalb des Symbols angezeigt. Der anzuzeigende Text wird als Wert erwartet. }}} == Mit Fenster == === Quellcode === {{{#!code bash #!/bin/bash exec 3> >(zenity --progress --title="Sicherung" --percentage=0 --auto-close --width=400) echo "# Ermittle Dateien..." >&3 count=$(find ${1-.} | wc -l) # Anzahl der Dateien IFS=' ' # wegen Dateien mit Leerzeichen i=0 for file in $(find ${1-.}) do i=$(($i+1)); echo $(($i*100/$count)) >&3; if [ -d $file ]; then continue; fi #Verzeichnisse überspringen echo "# Datei '$file' wird gesichert..." >&3; echo "Datei '$file' wird gesichert..."; # hier das einsetzen was mit der Datei gemacht werden soll. done echo Fertig. exec 3>&- }}} === Erläuterungen === * Zenity wird geöffnet (Bedeutung der Optionen siehe Manpage) * `find ${1-.} | wc -l` - Die Anzahl der Dateien für die Fortschrittsanzeige wird ermittelt und das Ergebnis der Variablen `$count` zugewiesen * In einer Schleife werden alle Dateien verarbeitet (`$IFS` bestimmt, an welchen Zeichen eine neue Datei beginnt) * `$(($i*100/$count))` - Errechnung der Prozentzahl * `echo "# Datei '$file' wird gesichert..." >&3;` - Zahlen werden von Zenity als Prozentsatz interpretiert, `# Text` bestimmt den Anzeigetext = Probleme und Lösungen = Bei jedem Aufruf von Zenity erscheint im Terminal eine Warnung {{{ Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged. }}} Der Eintrag an sich ist harmlos, stört ggf. aber die Übersicht erheblich. Man wird ihn los, indem man im Skript jeden zenity-Aufruf mit einem ans jeweilige Zeilenende gesetztem {{{ 2> dev/null }}} die Meldung ins Nirvana schickt. = Links = * [gnomeprojects:Zenity:Projektseite] {en} * [https://help.gnome.org/users/zenity/3.24/index.html.de Handbuch] {de} * [:Scrot#Skripte: Bildschirmfotos mit Zenity-Oberfläche] – Skriptbeispiel * [:Nautilus/Skripte/SMBsession: SMB-Freigaben ohne SMBv1 einbinden] – Skriptbeispiel # tag: GNOME, Programmierung, System