Notification de bureau à la fin des commandes en cours d'exécution

49

J'aimerais avoir une notification sur le bureau chaque fois qu'une commande qui a duré plus de 15 secondes, par exemple, se termine dans un shell interactif.

En d'autres termes, je voudrais que toutes les commandes soient enveloppées de quelque chose comme ça

start=$(date +%s);
ORIGINAL_COMMAND;
[ $(($(date +%s) - start)) -le 15 ] || notify-send "Long running command finished"

Quelle est la meilleure façon d’y parvenir en bash?

    
posée aioobe 23.01.2014 - 12:57
la source

9 réponses

20

Vous voulez lien (installable à partir des archives Ubuntu avec sudo apt-get install undistract-me ) qui fait précisément ce que vous demandez, y compris travailler automatiquement (c’est-à-dire sans avoir à vous souvenir d’ajouter quelque chose de plus à des commandes potentiellement longues).

    
réponse donnée sil 03.05.2015 - 17:37
la source
30

Si j'ai bien compris, vous voulez un wrapper . Et vous voulez utiliser une commande à travers elle pour qu'elle vous avertisse si le temps d'exécution de votre commande est supérieur à 15 secondes. Alors voilà.

wrapper(){
    start=$(date +%s)
    "[email protected]"
    [ $(($(date +%s) - start)) -le 15 ] || notify-send "Notification" "Long\
 running command \"$(echo [email protected])\" took $(($(date +%s) - start)) seconds to finish"
}

Copiez cette fonction dans vos ~/.bashrc et source ~/.bashrc as,

. ~/.bashrc

Utilisation

wrapper <your_command>

Si cela prend plus de 15 secondes, vous recevrez la notification du bureau décrivant la commande et son heure d’exécution.

Exemple

wrapper sudo apt-get update

    
réponse donnée souravc 23.01.2014 - 20:29
la source
24

Dans ~/.bashrc , il existe un alias alert défini comme:

alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

qui peut être utilisé pour notifier l'achèvement de l'exécution de la commande.

Utilisation:

$ the_command; alert

p. ex.

$ sudo apt-get update; alert

Vous pouvez personnaliser l’alias selon vos besoins et désirs.

    
réponse donnée precise 23.01.2014 - 20:23
la source
13

En dehors d’un wrapper comme celui proposé par souravc, il n’ya pas vraiment de moyen de le faire en bash. Vous pouvez le contourner avec un piège DEBUG et un PROMPT_COMMAND. Un piège DEBUG est déclenché chaque fois que vous exécutez une commande et PROMPT_COMMAND est exécuté juste avant que l'invite ne soit écrite.

Donc, les choses pour ~/.bashrc deviennent quelque chose comme

trap '_start=$SECONDS' DEBUG
PROMPT_COMMAND='(if (( SECONDS - _start > 15 )); then notify-send "Long running command ended"; fi)'

Ceci est un hack, donc ne soyez pas surpris si vous rencontrez des effets secondaires étranges avec cela.

    
réponse donnée geirha 23.01.2014 - 21:07
la source
4

EDIT

TL; DR : crée un raccourci d’auto-complétion dans .inputrc et fonctionne dans .bashrc . Exécutez la commande comme d'habitude, tapez, mais au lieu de ENTER , appuyez sur le raccourci que vous avez spécifié dans .inputrc

La personne qui a placé la prime sur cette question a dit:

  

"Toutes les réponses existantes nécessitent de taper une commande supplémentaire   après la commande. Je veux une réponse automatique. "

En recherchant les solutions à ce problème, je suis tombé sur cette question de stackexchange, qui autorise la liaison Ctrl J à une séquence de commandes: Ctrl a (déplacez-vous au début de la ligne), placez la chaîne "mesure" devant de la commande que vous avez entrée, Ctrl m (exécutez)

Ainsi, vous obtenez la fonctionnalité de complétion automatique et séparez la commande ENTER pour mesurer le temps, tout en conservant l'objectif initial de la deuxième fonction que j'ai publiée ci-dessous.

À ce jour, voici le contenu de mon fichier ~/.inputrc :

"\C-j": "\C-a measure \C-m"

Et voici le contenu de .bashrc (notez que je n’ai pas utilisé bash pour toujours - j’utilise mksh comme shell, c’est donc ce que vous voyez dans le message original. La fonctionnalité est toujours la même)

PS1=' [email protected] [$(pwd)]
================================
$ '
function measure () 
{

/usr/bin/time --output="/home/xieerqi/.timefile" -f "%e" [email protected] 

if [ $( cat ~/.timefile| cut -d'.' -f1 ) -gt 15 ]; then

    notify-send "Hi , [email protected] is done !"

fi


}

Message original

Voici mon idée - utilisez une fonction dans .bashrc . Principe de base - utilisez /usr/bin/time pour mesurer le temps nécessaire à l'exécution de la commande et, s'il est supérieur à 15 secondes, envoyez une notification.

function measure () 
{

if [ $( /usr/bin/time -f "%e" [email protected] 2>&1 >/dev/null ) -gt 15 ]; then

    notify-send "Hi , [email protected] is done !"

fi


}

Ici, je redirige la sortie vers /dev/null mais pour voir la sortie, il est également possible de rediriger vers un fichier.

Une meilleure approche, à mon humble avis, consiste à envoyer la sortie de temps à certains fichiers de votre dossier personnel (juste pour ne pas polluer votre système avec des fichiers de temps et toujours savoir où chercher). Voici cette deuxième version

function measure () 
{

/usr/bin/time --output=~/.timefile -f "%e" [email protected] 

if [ $( cat ~/.timefile | cut -d'.' -f1 ) -gt 15 ]; then

    notify-send "Hi , [email protected] is done !"

fi


}

Et voici les captures d'écran de la première et de la deuxième version, dans cet ordre

Première version, pas de sortie

Deuxième version, avec sortie

    
réponse donnée Sergiy Kolodyazhnyy 04.05.2015 - 01:31
la source
3

J'ai récemment construit un outil qui sert cet objectif. Il peut être exécuté comme un wrapper ou automatiquement avec l'intégration du shell. Découvrez-le ici: lien

Pour l'installer:

sudo pip install ntfy

Pour l'utiliser comme un wrapper:

ntfy done sleep 3

Pour recevoir les notifications automatiquement, ajoutez-les à votre .bashrc ou .zshrc :

eval "$(ntfy shell-integration)"
    
réponse donnée Daniel Schep 04.03.2016 - 22:51
la source
1

Votre script fonctionne assez bien, assurez-vous d'inclure le 'shebang' ( #!/bin/bash ) ligne . Les autres pour #!/bin/bash sont mentionnés ici , mais la plupart du temps, #!/bin/bash fonctionne bien pour Scripts bash Unix. Il est requis par l'interpréteur de script pour qu'il sache quel type de script c'est.

Cela semble fonctionner comme un script de test:

#!/bin/bash
start=$(date +%s);
   echo Started
   sleep 20;
   echo Finished!
[ $(($(date +%s) - start)) -le 15 ] || notify-send -i dialog-warning-symbolic "Header" "Message"

Pour modifier ce script, placez la ou les commandes où se trouvent les lignes echo et sleep .

Remarque avec notify-send , vous pouvez utiliser -i pour spécifier également une icône: -)

Assurez-vous également qu’il est exécutable en exécutant chmod +x /PATH/TO/FILE dessus.

    
réponse donnée Wilf 23.01.2014 - 18:54
la source
1

Vous pouvez modifier Bash pour implémenter la fonctionnalité de wrapper souhaitée.

Si vous souhaitez apporter de nombreuses modifications de ce type à votre shell interactif, vous pouvez envisager de passer à un shell intrinsèquement piratable tel que eshell, qui utilise Emacs elisp et offre toutes ses possibilités de personnalisation:

lien

    
réponse donnée Ryan Prior 30.04.2014 - 14:21
la source
-2

Vous pouvez également faire cela avec une simple instruction if comme celle-ci

#!/bin/bash

START=$(date +%s)

TIME=$(($START+15))

ORIGINAL_COMMAND;

END=$(date +%s)

if [ $END -gt $TIME ]
then
    notify-send "Task Completed"
fi

Vous pouvez utiliser vos propres noms de variables.

Je peux confirmer que cela fonctionne, j'ai testé avec une commande qui prend beaucoup de temps pour finir et une autre qui ne le fait pas et la notification vient pour celle qui prend beaucoup de temps

Vous pouvez également le faire avec n'importe quelle commande en remplaçant ORIGINAL_COMMAND par [email protected] et en exécutant le script sous la forme ./script command .

    
réponse donnée Rumesh 03.05.2015 - 17:31
la source

Lire d'autres questions sur les étiquettes