web-dev-qa-db-fra.com

Notification du bureau lorsque de longues commandes sont terminées

J'aimerais recevoir une notification sur le bureau chaque fois qu'une commande exécutée depuis plus de, disons, 15 secondes se termine dans un shell interactif.

En d'autres termes, je voudrais que toutes les commandes soient emballées dans quelque chose comme ceci

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

Quelle est la meilleure façon d'accomplir cela à bash?

57
aioobe

Vous voulez https://launchpad.net/undistract-me (installable à partir des archives Ubuntu avec Sudo apt-get install undistract-me) qui fait exactement ce que vous demandez, y compris le travail automatique (c'est-à-dire sans avoir à vous souvenir d'ajouter quelque chose d'extra à des commandes potentiellement longues).

23
sil

D'après ce que j'ai compris, vous voulez un wrapper . Et vous voulez utiliser une commande à travers elle pour qu'elle vous donne la notification souhaitée si le temps d'exécution de votre commande est supérieur à 15 secondes. Alors voilà.

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

Copiez cette fonction dans votre ~/.bashrc et votre source ~/.bashrc en tant que,

. ~/.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

screenshot of desktop-nitification

32
souravc

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

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.

Usage:

$ the_command; alert

par exemple.

$ Sudo apt-get update; alert

snap1

Vous pouvez personnaliser le pseudonyme selon vos besoins et vos désirs.

26
precise

À part un emballage comme suggéré par souravc, il n’existe pas vraiment de bonne façon de faire cela en bash. Vous pouvez y faire un détour avec un piège DEBUG et un Prompt_COMMAND. Une interruption DEBUG est déclenchée chaque fois que vous exécutez une commande et Prompt_COMMAND est exécuté juste avant que l'invite ne soit écrite.

Donc, trucs pour ~/.bashrc devient 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, alors ne soyez pas surpris si vous rencontrez des effets secondaires bizarres avec cela.

13
geirha

EDIT

TL; DR : crée un raccourci pour l'auto-complétion dans .inputrc et une fonction 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 déclaré:

"Toutes les réponses existantes nécessitent la saisie d'une commande supplémentaire après la commande. Je souhaite une réponse qui le fasse automatiquement."

En cherchant les solutions à ce problème, je suis tombé sur this question de stackexchange, qui permet de lier CtrlJ à une séquence de commandes: Ctrla (déplacez-vous au début de la ligne), placez la chaîne "mesure" devant la commande que vous avez entrée, Ctrlm (exécuter)

Ainsi, vous obtenez une fonctionnalité de saisie automatique et séparée ENTER commande de mesure du temps, tout en préservant le but initial de la seconde fonction i postée ci-dessous.

Pour l'instant, voici le contenu de mon fichier ~/.inputrc:

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

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

PS1=' serg@ubuntu [$(pwd)]
================================
$ '
function measure () 
{

/usr/bin/time --output="/home/xieerqi/.timefile" -f "%e" $@ 

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

    notify-send "Hi , $@ 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 dépasse 15 secondes, envoyez une notification.

function measure () 
{

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

    notify-send "Hi , $@ is done !"

fi


}

Ici, je redirige la sortie vers /dev/null mais pour afficher la sortie, la redirection vers un fichier peut également être effectuée.

Une approche bien meilleure, à mon humble avis, consiste à envoyer la sortie de temps à un fichier de votre dossier personnel (pour que vous ne pollriez pas votre système avec des fichiers de temps et que vous sachiez toujours où regarder). Voici cette deuxième version

function measure () 
{

/usr/bin/time --output=~/.timefile -f "%e" $@ 

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

    notify-send "Hi , $@ is done !"

fi


}

Et voici les captures d'écran des première et deuxième versions, dans cet ordre

Première version, pas de sortie enter image description here

Deuxième version, avec sortie enter image description here

4

J'ai récemment construit un outil qui sert cet objectif. Il peut être exécuté en tant que wrapper ou automatiquement avec l'intégration de Shell. Vérifiez-le ici: http://ntfy.rtfd.io

Pour l'installer:

Sudo pip install ntfy

Pour l'utiliser comme un wrapper:

ntfy done sleep 3

Pour recevoir des notifications automatiquement, ajoutez ceci à votre .bashrc ou .zshrc:

eval "$(ntfy Shell-integration)"
3
Daniel Schep

Vous pouvez modifier Bash pour implémenter la fonctionnalité d'encapsulage souhaitée.

Si vous êtes enclin à apporter de nombreuses modifications de ce type à votre shell interactif, vous pouvez envisager de passer à un shell intrinsèquement hackable comme eshell, construit à l'aide d'Emacs elisp et doté de toutes les possibilités de personnalisation suivantes:

http://www.masteringemacs.org/articles/2010/12/13/complete-guide-mastering-eshell/

1
Ryan Prior

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

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.

Notez que avec notify-send, vous pouvez aussi utiliser -i pour spécifier une icône :-)

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

1
Wilf