Gibt es eine Möglichkeit, ein Symbol nur anzuzeigen, während mein Skript ausgeführt wird?

10

Ich bin sehr, sehr neu in der Skripterstellung. Hier ist das einfache Skript (das funktioniert), das ich geschrieben habe und das nach Ablauf von 5 Minuten ein Bild anzeigt:

sleep 300 && firefox file:///home/tasks/fiveminutes.jpg

Hier ist meine Frage: Manchmal kann ich mich nicht erinnern, ob ich den Timer gestartet habe. Gibt es eine Möglichkeit, eine Text- oder Symbolanzeige (idealerweise in der Taskleiste, aber überall wäre großartig) hinzuzufügen, die 5 Minuten lang angezeigt wird (vom Start des Timers bis zum Ende des Timers)?

Vielen Dank für alle Vorschläge.

Salbei .
quelle
1
Bash ist nicht der beste Weg, um Desktop-Funktionen zu handhaben. Sie könnten Zenity oder Yad betrachten, aber sie funktionieren nicht so gut mit einer Schlaffunktion. Wenn Sie Python verwenden möchten, ist dies ein sehr einfaches Skript, das ein GTK / wx-Taskleistensymbol verwenden kann.
Dorian
Für eine komplexere Bash-Lösung mit Zenity können Sie sich diesen Code ansehen: github.com/john-davies/shellpomo/blob/master/shellpomo
Dorian
Hallo Dorian - Vielen Dank für deine Vorschläge. Ich würde gerne Python verwenden. Können Sie mir eine Anleitung für das Taskleistensymbol GTK / wx geben?
Salbei.

Antworten:

4

Sie können eine Popup-Benachrichtigung anzeigen, wenn der Prozess startet. Ändern Sie einfach Ihr Skript in

notify-send "Your image will arrive" "after 5 minutes" && sleep 300 && firefox file:///home/tasks/fiveminutes.jpg

Sie können die Dauer der Benachrichtigungsblase mit dem -tParameter (und der Zeit in Millisekunden) mit dem notify-sendBefehl festlegen, um beispielsweise die Dauer für die Verwendung von 5 Minuten festzulegen

notify-send -t 300000 "heading" "text"

aber dieser Parameter vollständig ignoriert werden kann abhängig von Ihrer Desktop - Umgebung (siehe diese ).

pomsky
quelle
Hallo Pomsky, danke für deinen Vorschlag. Was ich suche, ist etwas, das für die gesamten 5 Minuten auf dem Bildschirm bleibt.
Salbei.
1
@Salbei. Es gibt eine Möglichkeit, das Zeitlimit für die Benachrichtigungsblase festzulegen (siehe Bearbeiten der Antwort), aber in bestimmten Desktop-Umgebungen funktioniert dies möglicherweise nicht.
Pomsky
Hallo Pomsky - die Benachrichtigungs-Sende-Lösung funktioniert wie ein Traum. Ich schätze deine Hilfe sehr.
Salbei.
6

Es reicht aus, ein Skript wie das folgende zu haben:

#!/usr/bin/env bash

while true
do
    if pgrep -f gedit > /dev/null
    then

       printf "\r%b" "\033[2K"
       printf "Script is running"
    else
       printf "\r%b" "\033[2K" 
       printf "Script is not running."
    fi
    sleep 0.25
done

Dies ist eine sehr typische Methode und wird häufig in Shell-Skripten verwendet. Dies führt zu einer kontinuierlichen Ausführung und überprüft jede Viertelsekunde, ob Ihr Skript über ausgeführt wird pgrep -f. if..fiAnweisungen in Shell-Skripten arbeiten mit dem Exit-Status von Befehlen. pgrep -fWenn Sie also den erfolgreichen Exit-Status zurückgeben, wird der Prozess Ihres Skripts gefunden und ausgeführt. Ansonsten gehen wir zur else-Anweisung.

In beiden Fällen drucken wir eine Textzeile, die dem Benutzer mitteilt, ob sie ausgeführt wird oder nicht. Es wurde auch printf "\r%b" "\033[2K"eine Drucksequenz zum Löschen der Zeile gedruckt (nur für eine sauberere Ausgabe).

Von dort ist der Himmel die Grenze. Sie können diesen Text per Pipe an einen anderen Prozess im Terminal übergeben oder die Ausgabe des Überwachungsskripts an den Indikator-Sysmonitor übergeben , der die Anzeige benutzerdefinierter Informationen im Indikator ermöglicht. Es kann über installiert werden

sudo add-apt-repository ppa:fossfreedom/indicator-sysmonitor
sudo apt-get update
sudo apt-get install indicator-sysmonitor

Konfigurieren Sie danach einfach den Indikator so, dass ein benutzerdefinierter Befehl angezeigt wird, der das Überwachungsskript ist. Ein Beispiel für die Konfiguration eines benutzerdefinierten Befehls finden Sie hier .

Natürlich könnte man in Python einen eigenen Indikator schreiben, aber dies könnte nur ein Overkill sein, wenn es dafür bereits ein Tool gibt.

Sergiy Kolodyazhnyy
quelle
1
indicator-sysmonitorklingt nützlich, ich sollte es versuchen.
pa4080
6

Hier ist Python Launcher, basierend auf dieser Antwort und einer zusätzlichen Recherche im Internet, die in Ubuntu 16.04 gut funktioniert:

#!/usr/bin/env python3
import signal
import gi
import os
import subprocess
import sys
gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
from gi.repository import Gtk, AppIndicator3, GObject
import time
from threading import Thread

# Execute the script
script = os.path.basename(sys.argv[1])
subprocess.Popen(sys.argv[1:])
script_name = script.rsplit('/', 1)[-1]

class Indicator():
    def __init__(self):
        self.app = 'Script indicator'
        iconpath = "/usr/share/unity/icons/launcher_bfb.png"

        self.indicator = AppIndicator3.Indicator.new(
            self.app, iconpath,
            AppIndicator3.IndicatorCategory.OTHER)
        self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
        self.indicator.set_menu(self.create_menu())
        self.indicator.set_label("Script Indicator", self.app)
        # the thread:
        self.update = Thread(target=self.show_seconds)
        # daemonize the thread to make the indicator stopable
        self.update.setDaemon(True)
        self.update.start()

    def create_menu(self):
        menu = Gtk.Menu()
        # menu item 1
        item_quit = Gtk.MenuItem('Quit')
        item_quit.connect('activate', self.stop)
        menu.append(item_quit)

        menu.show_all()
        return menu

    def show_seconds(self):
        global script_name
        t = 0
        process = subprocess.call(['pgrep', script_name], stdout=subprocess.PIPE)
        while (process == 0):
            t += 1
            GObject.idle_add(
                self.indicator.set_label,
                script_name + ' ' + str(t) + 's', self.app,
                priority=GObject.PRIORITY_DEFAULT
                )
            time.sleep(1)
            process = subprocess.call(['pgrep', script_name], stdout=subprocess.PIPE)

        subprocess.call(['notify-send', script_name + ' ended in ' + str(t) + 's'])
        time.sleep(10)
        Gtk.main_quit()

    def stop(self, source):
        global script_name
        subprocess.call(['pkill', script_name], stdout=subprocess.PIPE)
        Gtk.main_quit()

Indicator()
# this is where we call GObject.threads_init()
GObject.threads_init()
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()
  • Wenn Sie eine Möglichkeit zur Verbesserung des Skripts sehen, zögern Sie bitte nicht, die Antwort zu bearbeiten. Ich habe nicht viel Erfahrung mit Python.

Erstellen Sie eine ausführbare Datei und platzieren Sie die obigen Zeilen als Inhalt. Nehmen wir an, die Datei wird aufgerufen script-indicator.py. Abhängig von Ihren Anforderungen und Ihrer Skriptart können Sie diesen Launcher auf eine der folgenden Arten verwenden:

./script-indicator.py /path/to/script.sh
./script-indicator.py /path/to/script.sh &
./script-indicator.py /path/to/script.sh > out.log &
./script-indicator.py /path/to/script.sh > /dev/null &
  • Wo script.shmöchten Sie angeben?

Screenshot gemacht, wenn das script.shbeendet ist:

Geben Sie hier die Bildbeschreibung ein

  • Klicken Sie auf das Bild, um eine animierte Demo zu sehen.

Alternativ können Sie das Skript so platzieren /usr/local/bin, dass es systemweit als Shell-Befehl zugänglich ist. Sie können es von diesem speziellen GitHub Gist herunterladen :

sudo wget -qO /usr/local/bin/script-indicator https://gist.githubusercontent.com/pa4080/4e498881035e2b5062278b8c52252dc1/raw/c828e1becc8fdf49bf9237c32b6524b016948fe8/script-indicator.py
sudo chmod +x /usr/local/bin/script-indicator

Ich habe es mit der folgenden Syntax getestet:

script-indicator /path/to/script.sh
script-indicator /path/to/script.sh &
script-indicator /path/to/script.sh > output.log
script-indicator /path/to/script.sh > output.log &
script-indicator /path/to/script.sh > /dev/null
script-indicator /path/to/script.sh > /dev/null &
nohup script-indicator /path/to/script.sh >/dev/null 2>&1 &
# etc...
pa4080
quelle
2
Gut gemacht ! Bereits upvoted
Sergiy Kolodyazhnyy
4

Mit osd_cat

Sie können osd_cataus dem xosd-bin Installieren Sie xosd-binPaket verwenden, zB:

<<<"runs" osd_cat -d5 -i20 -o50 -f"-*-*-*-*-*-*-100-*-*-*-*-*-*-*" && firefox

Dies zeigt "Läuft" mit der Schriftgröße 100für 5Sekunden an der Position 20,50auf dem Bildschirm an und startet, firefoxwenn es fertig ist - das brauchen Sie sleepbei diesem Ansatz nicht. Sie können xfontselden X Logical Font Descriptor (dieses seltsame -*-*-…Ding) für die -fOption verwenden, z. B. wenn Sie eine andere Schriftart verwenden möchten. Lesen Sie man osd_catfür weitere Optionen.

Mit yad

Sie können yad Installieren Sie yadFolgendes verwenden:

yad --title=runs --text="it’s running!" --timeout=5 --button=Fire:1 --button=Abort:0 || firefox

Dies hat den Vorteil, dass Sie den Befehl abbrechen oder sofort ausführen können. Wenn Sie nichts tun, wird er 5in diesem Beispiel nach Sekunden geschlossen.

Dessert
quelle
Hallo Dessert - danke für deinen Vorschlag. Was ich suche, ist etwas, das für die gesamten 5 Minuten auf dem Bildschirm bleibt.
Salbei.
@Salbei. beide tun das, das yadfenster kann minimiert werden, der osd text kann nicht.
Nachtisch
@Salbei. Ich habe die beiden vorgeschlagenen Lösungen getestet und sie funktionieren ziemlich gut.
pa4080
0

Sie können dieses bereits funktionierende Skript verwendenmulti-timer und den Großteil davon für einen generischen Countdown-Timer entfernen:

spinning pizza.gif

Es wird dasselbe verwendet, das indicator-sysmonitorin Serges Antwort beschrieben ist.

Der Systray-Teil Brightness: 2344wird ebenfalls von demselben Skript angezeigt.

Wenn es für neue Benutzer zu schwierig ist, nicht benötigte Teile des Bash-Codes zu entfernen, würde ich gerne hier ein Skript show-sleepmit der erforderlichen eingeschränkten Funktionalität veröffentlichen. Schreiben Sie einfach einen Kommentar unten.

WinEunuuchs2Unix
quelle