डेस्कटॉप अधिसूचना जब लंबे समय से चल रही कमांड पूरी हो जाती है


59

जब भी कोई कमांड 15 सेकंड से अधिक समय के लिए चलता है, एक इंटरैक्टिव शेल में समाप्त होता है, तो मैं एक डेस्कटॉप अधिसूचना करना चाहता हूं।

दूसरे शब्दों में, मैं चाहूंगा कि सभी आदेश इस तरह से लपेटे जाएं

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

बैश में इसे पूरा करने का सबसे अच्छा तरीका क्या है?




आपने अभी-अभी "इंटरेक्टिव शेल" में क्यों जोड़ा? यह कुछ मौजूदा उत्तरों को अमान्य कर सकता है जो आपके मूल पद के संदर्भ में एक वर्ष से अधिक समय से मौजूद थे। यदि आपको विशेष रूप से इंटरेक्टिव शेल के लिए समाधान की आवश्यकता है, तो इस एक को संदर्भित करते हुए अलग प्रश्न पूछने पर विचार करें।
सर्गी कोलोडियाज़नी

"इंटरेक्टिव शेल" भाग को संपादित करने से पहले पहली टिप्पणी में स्पष्ट किया गया था। मैंने केवल प्रश्न संपादित किया और टिप्पणी को हटा दिया। इसके अलावा, सवालों में तैनात 3 लाइनें एक स्क्रिप्ट के लिए अच्छी तरह से काम करती हैं।
शाम

जवाबों:


24

आप https://launchpad.net/undistract-me (उबंटू अभिलेखागार से स्थापित होना चाहते हैं sudo apt-get install undistract-me) जो ठीक उसी तरह से करता है जो आप खुद से काम करने के लिए कहते हैं, (जो कि, संभवतः लंबे समय तक कुछ अतिरिक्त जोड़ने के लिए याद किए बिना है- रनिंग कमांड्स)।


1
यह काम नहीं कर रहा है। मैंने इसे स्थापित किया, अपने सिस्टम को पुनः आरंभ किया और परीक्षण किया sleep 30, लेकिन कोई अधिसूचना नहीं।
गलगलेश

4
आप के लिए निम्न दो पंक्तियों जोड़ने की जरूरत है .bashrc: . /usr/share/undistract-me/long-running.bash notify_when_long_running_commands_finish_install। यह एक बग लगता है: github.com/jml/undistract-me/issues/23
लुडेंटिकस

32

जहां तक ​​मैंने समझा कि आप एक रैपर चाहते हैं । और आप इसके माध्यम से एक कमांड का उपयोग करना चाहते हैं ताकि यह आपको वांछित सूचना दे सके यदि आपकी कमांड का समय 15 सेकंड से अधिक हो। तो यहाँ है।

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

इस फ़ंक्शन को अपने ~/.bashrcऔर स्रोत में कॉपी करें ~/.bashrc,

. ~/.bashrc

useage

wrapper <your_command>

यदि यह 15 सेकंड से अधिक समय लेता है तो आपको कमांड और इसके निष्पादन के समय का वर्णन करने वाला डेस्कटॉप-अधिसूचना प्राप्त होगा।

उदाहरण

wrapper sudo apt-get update

डेस्कटॉप-नाइटिफिकेशन का स्क्रीनशॉट


1
"$@", नहीं $@। बड़ा अंतर।
जिरह

4
मैं wrapperहर कमांड के सामने लिखने से बचना चाहूँगा, हालाँकि मैं टाइप करता हूँ।
aioobe

2
@ aioobe आप एक छोटे फ़ंक्शन नाम का उपयोग कर सकते हैं यहां तक ​​कि एक पत्र भी हो सकता है। लेकिन एक आवरण इस तरीके से काम करता है।
--१३:

3
command; alertवास्तव में wrapper command:-) से कम है
aioobe

1
यदि आप notify-sendलंबे समय तक समाप्त नहीं होना चाहते हैं, तो नोटिफ़िकेशन-कस्टम टाइमआउट (मिलीसेकंड में) दें। जैसेnotify-send --expire-time 999999999 ...
ब्रायस गुइंटा

26

में ~/.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

snap1

आप अपनी आवश्यकता और इच्छा के अनुसार उपनाम को अनुकूलित कर सकते हैं।


3
पता चला तो अच्छा है। क्या मेरे द्वारा टाइप किए जाने वाले प्रत्येक आदेश के बाद सतर्कता बरतने का एक तरीका है (और यह भी चेतावनी है कि यदि कमांड को 15 सेकंड से अधिक समय हो गया है)?
aioobe

अजीब बात यह पहले से ही मेरे .bashrc में जोड़ा गया है, क्या यह ubuntu में डिफ़ॉल्ट है?
विग्नेश

13

सूप्रेक जैसे रैपर के अलावा सुझाव दिया गया है कि वास्तव में बैश में ऐसा करने का कोई अच्छा तरीका नहीं है। आप 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)'

यह एक हैक है, इसलिए यदि आप इसके साथ विषम दुष्प्रभावों का सामना करते हैं तो आश्चर्यचकित न हों।


4

संपादित करें

TL; DR : में .inputrcऔर फ़ंक्शन में स्वतः पूर्णता शॉर्टकट बनाएँ .bashrc । सामान्य रूप से कमांड चलाएं, जिसमें टाइप करें, लेकिन इसके बजाय ENTER, उस शॉर्टकट को दबाएं जिसे आपने निर्दिष्ट किया था.inputrc

इस सवाल पर इनाम रखने वाले व्यक्ति ने कहा:

"सभी मौजूदा उत्तरों को कमांड के बाद एक अतिरिक्त कमांड टाइप करने की आवश्यकता है। मुझे ऐसा उत्तर चाहिए जो यह स्वचालित रूप से करता हो।"

इस समस्या को मैं पर ठोकर खाई किया है करने के लिए समाधान शोध जबकि इस stackexchange से सवाल है, जो बंधन की अनुमति देता है CtrlJआदेशों की एक दृश्य करने के लिए: Ctrlaकमांड आपके द्वारा दर्ज के सामने जगह "मेसर" स्ट्रिंग, (पंक्ति के आरम्भ में ले जाते हैं) Ctrlm(अमल)

इस प्रकार आप ENTERसमय को मापने के लिए ऑटो-पूर्णता और अलग-अलग कमांड की कार्यक्षमता प्राप्त करते हैं, जबकि मैं दूसरे फ़ंक्शन के मूल उद्देश्य को बनाए रखता हूं ।

अब तक, यहाँ मेरी ~/.inputrcफ़ाइल की सामग्रियां हैं :

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

और यहाँ की सामग्री हैं .bashrc(ध्यान दें, मैं हमेशा के लिए बैश का उपयोग नहीं कर रहा हूं - मैं अपने शेल के रूप में एमएक्सएच का उपयोग करता हूं, इसलिए यह वही है जो आप मूल पोस्ट में देखते हैं। कार्यक्षमता अभी भी वही है)

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


}

मूल पोस्ट

यहाँ मेरा विचार है - एक फ़ंक्शन का उपयोग करें .bashrc। मूल सिद्धांत - /usr/bin/timeकमांड को पूरा करने में लगने वाले समय को मापने के लिए उपयोग करें, और यदि यह 15 सेकंड से अधिक है, तो अधिसूचना भेजें।

function measure () 
{

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

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

fi


}

यहां मैं आउटपुट को रीडायरेक्ट कर रहा हूं /dev/null, लेकिन आउटपुट देखने के लिए, फाइल को रीडायरेक्ट करना भी किया जा सकता है।

एक बेहतर दृष्टिकोण, IMHO, आपके घर के फ़ोल्डर में कुछ फ़ाइल के लिए समय का आउटपुट भेजना है (बस इसलिए कि आप अपने सिस्टम को टाइमफाइल्स के साथ प्रदूषित नहीं करते हैं, और हमेशा जानते हैं कि कहाँ देखना है)। यहाँ वह दूसरा संस्करण है

function measure () 
{

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

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

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

fi


}

और यहाँ पहले और दूसरे संस्करण के स्क्रीनशॉट हैं, उसी क्रम में

पहला संस्करण, कोई आउटपुट नहीं यहाँ छवि विवरण दर्ज करें

दूसरा संस्करण, आउटपुट के साथ यहाँ छवि विवरण दर्ज करें


वैसे, सुडो कमांड के साथ भी काम करता है। मैंने इसे sudo lsofऔर अधिकतर के साथ परीक्षण किया है ping -c20 google.com
सर्गी कोलोडियाज़नी

3

मैंने हाल ही में एक उपकरण बनाया है जो इस उद्देश्य को पूरा करता है। इसे या तो आवरण के रूप में चलाया जा सकता है या शेल एकीकरण के साथ स्वचालित रूप से। इसे यहाँ देखें: http://ntfy.rtfd.io

इसे स्थापित करने के लिए:

sudo pip install ntfy

एक आवरण के रूप में उपयोग करने के लिए:

ntfy done sleep 3

सूचनाएं स्वतः प्राप्त करने के लिए, इसे अपने .bashrcया .zshrc:

eval "$(ntfy shell-integration)"

1

आपकी स्क्रिप्ट काफी अच्छी तरह से काम करती है, बस यह सुनिश्चित करें कि आप 'shebang' ( #!/bin/bash) लाइन को शामिल करें। अन्य लोगों का #!/bin/bashउल्लेख यहां किया गया है , लेकिन ज्यादातर समय, #!/bin/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यह पहले इस पर चलने से निष्पादन योग्य है ।


1

आप इच्छित रैपर कार्यक्षमता को लागू करने के लिए बैश को संशोधित कर सकते हैं।

यदि आप अपने इंटरेक्टिव शेल में ऐसे कई संशोधन करने के लिए इच्छुक हैं, तो आप एस्केल जैसे आंतरिक रूप से हैक करने योग्य शेल पर स्विच करने पर विचार कर सकते हैं, जिसे Emacs elisp का उपयोग करके बनाया गया है और इसकी सभी मंजिला सीमाएं हैं:

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


-2

यदि आप इस तरह से बयान करते हैं तो आप इसे एक साधारण से भी कर सकते हैं

#!/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साथ बदलकर $@और चलाकर किसी भी कमांड के साथ भी कर सकते हैं ./script command


मेरा जवाब क्यों नहीं दिया गया? मैं जानना चाहता हूं कि मैं जवाब में गलत कहां हुआ
रमेश

मैंने इसे कम नहीं किया, लेकिन मैं आपको बताऊंगा कि इसमें क्या गलत है: सबसे पहले, इसे एक अतिरिक्त कमांड टाइप करने की आवश्यकता है। मैंने विशेष रूप से अपनी अमानत में कहा था कि मैं ऐसा नहीं करना चाहता। सभी का दूसरा, कैल्क क्यों? $((2+2))बैश बिलिन है, इसके लिए किसी अतिरिक्त कार्यक्रम की आवश्यकता नहीं है। तीसरा: यह उन आदेशों के साथ काम नहीं करता जिनके पास रिक्त स्थान हैं। tl; dr: यह अन्य 1 वर्ष पुराने उत्तरों से भी बदतर है
गलगलेश

खैर ..... शुरू और अंत समय अलग हो जाएगा, सही है? यहां तक ​​कि एक छोटी सी कमांड के लिए जो 1 सेकंड लंबी है
सर्गी कोलोडाज़हनी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.