Existe-t-il un moyen d'afficher une icône uniquement lorsque mon script est en cours d'exécution?

10

Je suis très, très nouveau dans les scripts. Voici le script simple (qui fonctionne) que j'ai écrit, qui affiche une image lorsque 5 minutes se sont écoulées:

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

Voici ma question: parfois, je ne me souviens pas si j'ai démarré la minuterie. Y a-t-il un moyen d'ajouter un texte ou une icône (idéalement dans la barre des tâches, mais n'importe où serait génial) qui apparaît pendant 5 minutes (du moment où je démarre le chronomètre au moment où je le termine)?

Merci beaucoup pour toutes suggestions.

Sauge .
la source
1
Bash n'est pas le meilleur moyen de gérer les fonctions du bureau. Vous pouvez regarder la zénité ou le yad, mais ils ne fonctionnent pas très bien avec une fonction de sommeil. Si vous envisagez d'utiliser Python, ce serait un script très simple qui pourrait utiliser une icône de barre d'état système GTK / wx.
Dorian
Pour une solution bash plus complexe avec zenity, vous pouvez consulter ce code: github.com/john-davies/shellpomo/blob/master/shellpomo
Dorian
Salut Dorian - Merci beaucoup pour vos suggestions. Je serais heureux d'utiliser Python, pouvez-vous me diriger vers un guide pratique pour l'icône de la barre d'état système GTK / wx?
Sauge.

Réponses:

4

Vous pouvez afficher une notification contextuelle au démarrage du processus. Changez simplement votre script en

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

Vous pouvez définir la durée de la bulle de notification avec le -tparamètre (et le temps en millisecondes) avec la notify-sendcommande, par exemple pour définir la durée de 5 minutes, utilisez

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

mais ce paramètre peut être complètement ignoré en fonction de votre environnement de bureau (voir ceci ).

pomsky
la source
Salut Pomsky, merci pour votre suggestion. Ce que je recherche, c'est quelque chose qui reste à l'écran pendant les 5 minutes.
Sauge.
1
@Sauge. Il existe un moyen de définir le délai d'expiration de la bulle de notification (voir modifier la réponse), mais malheureusement, il peut ne pas fonctionner dans certains environnements de bureau.
pomsky
Salut Pomsky - la solution notify-send -t fonctionne comme un rêve. J'apprécie vraiment votre aide.
Sauge.
6

Il suffit d'avoir un script comme ça:

#!/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

C'est une manière très typique et souvent utilisée dans les scripts shell. Ce que cela fait, s'exécute en continu, et chaque quart de seconde, il vérifie si votre script s'exécute via pgrep -f. if..fiLes instructions dans les scripts shell fonctionnent sur l'état de sortie des commandes, donc pgrep -fretourner un état de sortie réussi signifie qu'il a trouvé le processus de votre script et qu'il est en cours d'exécution. Sinon, nous passons à la déclaration else.

Dans les deux cas, nous imprimons une ligne de texte qui indique à l'utilisateur si elle fonctionne ou non. Il y a également ajouté printf "\r%b" "\033[2K"pour imprimer une séquence d'échappement pour effacer la ligne (juste pour une sortie plus propre).

De là, le ciel est la limite. Vous pouvez passer ce texte à un autre processus dans le terminal via un tuyau ou vous pouvez passer la sortie du script de surveillance à indicator-sysmonitor , ce qui permet d'afficher des informations personnalisées dans l'indicateur. Il peut être installé via

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

Après cela, configurez simplement l'indicateur pour afficher une commande personnalisée qui serait le script de surveillance. Un exemple de configuration d'une commande personnalisée peut être trouvé ici .

Bien sûr, on pourrait écrire leur propre indicateur en Python, mais cela pourrait être juste une surpuissance quand il existe déjà un outil pour cela.

Sergiy Kolodyazhnyy
la source
1
indicator-sysmonitorsemble utile, je devrais l'essayer.
pa4080
6

Voici le lanceur Python, basé sur cette réponse et une recherche supplémentaire sur Internet, qui fonctionne bien dans Ubuntu 16.04:

#!/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()
  • Si vous voyez un moyen d'améliorer le script, n'hésitez pas à modifier la réponse. Je n'ai pas beaucoup d'expérience avec Python.

Créez un fichier exécutable et placez les lignes ci-dessus comme son contenu. Supposons que le fichier soit appelé script-indicator.py. Selon vos besoins et la nature de votre script, vous pouvez utiliser ce lanceur de l'une des manières suivantes:

./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 &
  • script.shest celui que vous souhaitez indiquer.

Capture d'écran faite juste à la script.shfin du:

entrez la description de l'image ici

  • Cliquez sur l'image pour voir une démo animée.

Alternativement, vous pouvez placer le script /usr/local/binpour qu'il soit accessible en tant que système de commandes shell à l'échelle du système. Vous pouvez le télécharger à partir de ce GitHub Gist dédié :

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

Je l'ai testé avec la syntaxe suivante:

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
la source
2
Bon travail ! Déjà voté
Sergiy Kolodyazhnyy
4

Avec osd_cat

Vous pouvez utiliser à osd_catpartir du xosd-bin Installer xosd-binpackage, par exemple:

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

Cela affiche «exécute» avec la taille de la police 100pendant 5quelques secondes à la position 20,50sur l'écran et démarre firefoxquand il est prêt - vous n'avez pas besoin sleepde cette approche. Vous pouvez utiliser xfontselpour obtenir le descripteur de police logique X (ce -*-*-…truc bizarre ) pour l' -foption, par exemple si vous souhaitez utiliser une police différente. Lisez man osd_catpour plus d'options.

Avec yad

Vous pouvez utiliser yad Installez yadcomme suit:

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

Cela a l'avantage que vous pouvez abandonner la commande ou l'exécuter immédiatement, si vous ne faites rien, elle se fermera après 5quelques secondes dans cet exemple.

dessert
la source
Salut Dessert - merci pour votre suggestion. Ce que je recherche, c'est quelque chose qui reste à l'écran pendant les 5 minutes.
Sauge.
@Sauge. les deux font cela, la yadfenêtre peut être minimisée, le texte osd ne peut pas.
dessert
@Sauge. J'ai testé les deux solutions proposées et elles fonctionnent plutôt bien.
pa4080
0

Vous pouvez prendre ce script déjà fonctionnelmulti-timer et en retirer la majeure partie pour un compte à rebours générique:

spinning pizza.gif

Il utilise le même que celui indicator-sysmonitordécrit dans la réponse de Serge.

La partie Systray Brightness: 2344est également affichée par le même script.

Si supprimer les parties inutiles du code bash est trop difficile pour les nouveaux utilisateurs, je serais heureux de publier ici un script appelé show-sleepavec les fonctionnalités limitées nécessaires. Postez juste un commentaire ci-dessous.

WinEunuuchs2Unix
la source