Уведомление рабочего стола при завершении длинных команд

45

Я хотел бы получить уведомление на рабочем столе всякий раз, когда команда, которая запускалась более, чем, скажем, 15 секунд, заканчивается в интерактивной оболочке.

Другими словами, я хотел бы, чтобы все команды были обернуты чем-то вроде этого

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

Каков наилучший способ сделать это в bash?

    
задан aioobe 23.01.2014 в 12:57
источник

9 ответов

18

Вы хотите Ссылка (устанавливаемый из архивов Ubuntu с sudo apt-get install undistract-me ), который делает именно то, о чем вы просите, в том числе (то есть, не забывая добавлять что-то лишнее в потенциально длительные команды).     

ответ дан sil 03.05.2015 в 17:37
источник
29

Насколько я понял, вы хотите обертку . И вы хотите использовать команду через него, чтобы он дал вам желаемое уведомление, если время выполнения вашей команды больше 15 секунд. Вот и все.

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"
}

Скопируйте эту функцию в ~/.bashrc и source ~/.bashrc as,

. ~/.bashrc

Useage

wrapper <your_command>

Если потребуется более 15 секунд, вы получите уведомление на рабочем столе, описывающее команду и время ее выполнения.

Пример

wrapper sudo apt-get update

    
ответ дан souravc 23.01.2014 в 20:29
21

В ~/.bashrc есть псевдоним alert , определяемый как:

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$//'\'')"'

, который может быть использован для уведомления о завершении выполнения команды.

Использование:

$ the_command; alert

например.

$ sudo apt-get update; alert

Вы можете настроить псевдоним в соответствии с вашими потребностями и желаниями.

    
ответ дан precise 23.01.2014 в 20:23
11

Помимо обертки, такой как souravc, предположительно, нет никакого хорошего способа сделать это в bash. Вы можете взломать его с помощью ловушки DEBUG и PROMPT_COMMAND. Ловушка DEBUG запускается всякий раз, когда вы запускаете команду, а PROMPT_COMMAND запускается непосредственно перед написанием приглашения.

Итак, материал для ~/.bashrc становится чем-то вроде

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

Это взломать, так что не удивляйтесь, если вы столкнетесь с нечетными побочными эффектами.

    
ответ дан geirha 23.01.2014 в 21:07
4

ИЗМЕНИТЬ

TL; DR : создать ярлык автозаполнения в .inputrc и функцию в .bashrc . Запустите команду, как обычно, введите, но вместо ENTER нажмите сочетание клавиш, указанное в .inputrc

Человек, который разместил награду по этому вопросу, сказал:

  

«Все существующие ответы требуют ввода дополнительной команды   после команды. Я хочу получить ответ, который сделает это автоматически ».

При исследовании решений этой проблемы я наткнулся на этот вопрос из stackexchange, который позволяет привязывать Ctrl J к последовательности команд: Ctrl a (переход к началу строки), поместите строку «mesure» впереди команды, которую вы ввели, Ctrl m (выполнить)

Таким образом, вы получаете функциональность автозаполнения и отдельную команду ENTER для измерения времени, сохраняя первоначальную цель функции second , которую я написал ниже.

На данный момент вот содержимое моего файла ~/.inputrc :

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

И вот содержимое .bashrc (обратите внимание, что я не использовал bash навсегда - я использую mksh как свою оболочку, следовательно, это то, что вы видите в исходном сообщении. Функциональность все та же)

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


}

Оригинальная публикация

Вот моя идея - используйте функцию в .bashrc . Основной принцип - используйте /usr/bin/time , чтобы измерить время, необходимое для завершения команды, и если оно более 15 секунд, отправьте уведомление.

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


}

Здесь я перенаправляю вывод на /dev/null , но для просмотра вывода также можно перенаправить файл.

Намного лучше, IMHO, это отправить вывод времени в какой-нибудь файл в вашей домашней папке (просто чтобы вы не загрязняли свою систему таймифами и всегда знали, где искать). Вот вторая версия

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


}

И вот скриншоты первой и второй версий, в этом порядке

Первая версия, без вывода

Вторая версия, с выходом

    
ответ дан Sergiy Kolodyazhnyy 04.05.2015 в 01:31
3

Недавно я создал инструмент, который служит этой цели. Он может запускаться как оболочка или автоматически с интеграцией с оболочкой. Посмотрите здесь: Ссылка

Чтобы установить его:

sudo pip install ntfy

Использовать его как оболочку:

ntfy done sleep 3

Чтобы получать уведомления автоматически, добавьте это в свои .bashrc или .zshrc :

eval "$(ntfy shell-integration)"
    
ответ дан Daniel Schep 04.03.2016 в 22:51
1

Ваш скрипт работает достаточно хорошо, просто убедитесь, что вы включили «shebang» ( #!/bin/bash ) . Другие, относящиеся к #!/bin/bash , упоминаются здесь , но большую часть времени #!/bin/bash отлично работает для Скрипты Unix bash. Это требуется интерпретатору сценария, чтобы он знал, какой тип скрипта он имеет.

Это похоже на тестовый скрипт:

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

Чтобы изменить этот скрипт, поместите команды (ы), где находятся строки echo и sleep .

Обратите внимание, что notify-send , вы можете использовать -i , чтобы указать значок: -)

Кроме того, убедитесь, что он выполним, выполнив сначала chmod +x /PATH/TO/FILE .

    
ответ дан Wilf 23.01.2014 в 18:54
1

Вы можете изменить Bash, чтобы реализовать функциональность оболочки, которую вы хотите.

Если вы склонны делать много таких изменений в своей интерактивной оболочке, вы можете подумать о переходе на внутреннюю взломанную оболочку, такую ​​как eshell, которая построена с использованием Emacs elisp и имеет все свои легендарные возможности:

Ссылка

    
ответ дан Ryan Prior 30.04.2014 в 14:21
-2

Вы также можете сделать это с помощью простого оператора if, подобного этому

#!/bin/bash

START=$(date +%s)

TIME=$(($START+15))

ORIGINAL_COMMAND;

END=$(date +%s)

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

Вы можете использовать свои собственные имена переменных.

Я могу подтвердить, что это работает, я тестировал с помощью команды, которая занимает много времени, а другая - нет, и уведомление приходит для того, что занимает много времени.

Вы также можете сделать это с помощью любой команды, заменив ORIGINAL_COMMAND на [email protected] и запустив скрипт как ./script command .     

ответ дан Rumesh 03.05.2015 в 17:31