Existe uma maneira de exibir um ícone apenas enquanto meu script está em execução?

10

Eu sou muito, muito novo em scripts. Aqui está o script simples (que funciona) que eu escrevi, que exibe uma imagem após 5 minutos:

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

Aqui está minha pergunta: às vezes não me lembro se iniciei o cronômetro. Existe uma maneira de adicionar uma indicação de texto ou ícone (de preferência na barra de tarefas, mas em qualquer lugar seria ótimo) que apareça por 5 minutos (desde o momento em que inicio o cronômetro até o momento em que o encerro)?

Muito obrigado por todas as sugestões.

Sábio.
fonte
1
O Bash não é a melhor maneira de lidar com as funções da área de trabalho. Você pode olhar para o zenity ou o yad, mas eles não funcionam tão bem com a função de dormir. Se você considerar usar o Python, esse seria um script muito simples que poderia usar um ícone da bandeja do sistema GTK / wx.
Dorian
Para uma solução festa mais complexa com zenity, você pode ter um olhar para este código: github.com/john-davies/shellpomo/blob/master/shellpomo
Dorian
Oi Dorian - Muito obrigado por suas sugestões. Ficaria feliz em usar o Python, você pode me indicar um tutorial sobre o ícone da bandeja do sistema GTK / wx?
Sage.

Respostas:

4

Você pode exibir uma notificação pop-up quando o processo iniciar. Apenas mude seu script para

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

Você pode definir a duração do balão de notificação com o -tparâmetro (e o tempo em milissegundos) com o notify-sendcomando, por exemplo, para definir a duração por 5 minutos

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

mas esse parâmetro pode ser completamente ignorado, dependendo do ambiente da área de trabalho (veja isso ).

pomsky
fonte
Oi Pomsky, obrigado pela sua sugestão. O que estou procurando é algo que permanece na tela por 5 minutos inteiros.
Sage.
1
@Sábio. Há uma maneira de definir o tempo limite para o balão de notificação (consulte editar a resposta), mas infelizmente ele pode não funcionar em determinados ambientes da área de trabalho.
Pomsky # 25/18
Oi Pomsky - a solução de notificação-envio-t funciona como um sonho. Eu realmente aprecio sua ajuda.
Sage.
6

É suficiente o suficiente para ter um script como este:

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

Essa é uma maneira muito típica e frequentemente usada em scripts de shell. O que isso faz, está sendo executado continuamente e, a cada quarto de segundo, ele verifica se o seu script está sendo executado pgrep -f. if..fiAs instruções nos scripts de shell operam no status de saída dos comandos; portanto, pgrep -fretornar um status de saída bem-sucedido significa que encontrou o processo do script e está em execução. Caso contrário, vamos para a declaração else.

Nos dois casos, imprimimos uma linha de texto que informa ao usuário se está sendo executado ou não. Também foi adicionado printf "\r%b" "\033[2K"para imprimir uma sequência de escape para limpar a linha (apenas para uma saída mais limpa).

A partir daí, o céu é o limite. Você pode passar esse texto para outro processo no terminal via canal ou pode passar a saída do script de monitoramento para o indicador-sysmonitor , que permite exibir informações personalizadas no indicador. Pode ser instalado via

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

Depois disso, basta configurar o indicador para exibir um comando personalizado que seria o script de monitoramento. Exemplo de configuração de um comando personalizado pode ser encontrado aqui .

Obviamente, pode-se escrever seu próprio indicador em Python, mas isso pode ser apenas um exagero quando já existe uma ferramenta para isso.

Sergiy Kolodyazhnyy
fonte
1
indicator-sysmonitorparece útil, eu deveria tentar.
pa4080 26/05
6

Aqui está o iniciador do Python, com base nesta resposta e em uma pesquisa adicional na Internet, que funciona bem no 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()
  • Se você encontrar alguma maneira de melhorar o script, não hesite em editar a resposta. Eu não tenho muita experiência com Python.

Crie um arquivo executável e coloque as linhas acima como seu conteúdo. Vamos supor que o arquivo seja chamado script-indicator.py. Dependendo das suas necessidades e da natureza do script, você pode usar este iniciador de uma das seguintes maneiras:

./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 &
  • Onde script.shé o que você deseja indicar.

Captura de tela feita exatamente quando o script.shfinal é:

insira a descrição da imagem aqui

  • Clique na imagem para ver uma demonstração animada.

Como alternativa, você pode inserir o script /usr/local/binpara ser acessível como um sistema de comando shell. Você pode baixá-lo neste GitHub Gist dedicado :

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

Eu testei com a seguinte sintaxe:

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
fonte
2
Bom trabalho ! Já votado
Sergiy Kolodyazhnyy 26/05
4

Com osd_cat

Você pode usar osd_cato xosd-bin Instale xosd-binpacote, por exemplo:

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

Isso exibe "execuções" com o tamanho da fonte 100por 5segundos na posição 20,50na tela e inicia firefoxquando estiver pronto - você não precisa sleepdessa abordagem. Você pode usar xfontselpara obter o X Logical Font Descriptor (essa -*-*-…coisa estranha ) para a -fopção, por exemplo, se você quiser usar uma fonte diferente. Leia man osd_catpara mais opções.

Com yad

Você pode usar da yad Instalar yadseguinte maneira:

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

Isso tem a vantagem de poder interromper o comando ou executá-lo imediatamente, se você não fizer nada, ele será fechado após 5segundos neste exemplo.

sobremesa
fonte
Oi Sobremesa - obrigado pela sua sugestão. O que estou procurando é algo que permanece na tela por 5 minutos inteiros.
Sage.
@Sábio. ambos fazem isso, a yadjanela pode ser minimizada, o texto osd não.
sobremesa
@Sábio. Testei as duas soluções propostas e elas funcionam muito bem.
pa4080
0

Você pode pegar esse script que já está funcionandomulti-timer e retirar a maior parte dele para um cronômetro de contagem regressiva genérico:

spinning pizza.gif

Ele usa o mesmo indicator-sysmonitordescrito na resposta de Serge.

A parte do Systray Brightness: 2344também é exibida pelo mesmo script.

Se retirar partes desnecessárias do código bash for muito difícil para novos usuários, eu ficaria feliz em publicar um script aqui chamado show-sleepcom a funcionalidade limitada necessária. Basta postar um comentário abaixo.

WinEunuuchs2Unix
fonte