การแจ้งเตือนบนเดสก์ท็อปเมื่อคำสั่งที่รันเป็นเวลานานเสร็จสมบูรณ์


59

ฉันต้องการได้รับการแจ้งเตือนทางเดสก์ท็อปเมื่อใดก็ตามที่คำสั่งที่ใช้งานมานานกว่า 15 วินาทีในเชลล์เชิงโต้ตอบ

กล่าวอีกนัยหนึ่งฉันต้องการห่อหุ้มคำสั่งทั้งหมดในลักษณะนี้

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

อะไรคือวิธีที่ดีที่สุดในการทำสิ่งนี้ให้สำเร็จในการทุบตี?


1
เป็นไปได้เช่นเดียวกันกับ Superuser: superuser.com/questions/31917/ …
Ciro Santilli 事件改造中心中心法轮功六四事件


ทำไมคุณถึงเพิ่ม "ในเชลล์เชิงโต้ตอบ" ตอนนี้? มันอาจทำให้คำตอบที่มีอยู่ในบริบทของโพสต์ต้นฉบับของคุณเป็นโมฆะมานานกว่าหนึ่งปี หากคุณต้องการวิธีแก้ปัญหาเฉพาะสำหรับเชลล์แบบโต้ตอบให้ลองถามคำถามแยกต่างหากอ้างอิงคำถามนี้
Sergiy Kolodyazhnyy

ส่วน "เชลล์โต้ตอบ" ได้รับการชี้แจงในความคิดเห็นแรกก่อนที่จะแก้ไข ฉันเพียงแค่แก้ไขคำถามและลบความคิดเห็น นอกจากนี้ 3 บรรทัดที่โพสต์ในคำถามนั้นใช้งานได้ดีสำหรับสคริปต์
aioobe

คำตอบ:


24

คุณต้องการhttps://launchpad.net/undistract-me (ติดตั้งได้จากคลังเก็บของ Ubuntu ด้วยsudo apt-get install undistract-me) ซึ่งทำสิ่งที่คุณต้องการอย่างแม่นยำรวมถึงการทำงานโดยอัตโนมัติ ใช้คำสั่ง)


1
ดูเหมือนจะไม่ทำงาน ฉันติดตั้งแล้วรีสตาร์ทระบบและทดสอบด้วยsleep 30แต่ไม่มีการแจ้งเตือน
Galgalesh

4
คุณต้องเพิ่มสองบรรทัดต่อไป:.bashrc . /usr/share/undistract-me/long-running.bash notify_when_long_running_commands_finish_installดูเหมือนว่าจะเป็นข้อผิดพลาด: github.com/jml/undistract-me/issues/23
Ludenticus

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
"$@"$@ไม่ แตกต่างใหญ่
geirha

4
ฉันต้องการหลีกเลี่ยงการเขียนwrapperต่อหน้าทุกคำสั่งที่ฉันพิมพ์
aioobe

2
@aioobe คุณสามารถใช้ชื่อฟังก์ชั่นที่สั้นลงได้แม้จะเป็นตัวอักษร แต่เสื้อคลุมทำงานในลักษณะนี้
souravc

3
command; alertในความเป็นจริงสั้นกว่าwrapper command:-)
aioobe

1
หากคุณไม่ต้องการที่notify-sendจะหมดอายุเป็นเวลานานจากนั้นให้แจ้งเตือน - ส่งหมดเวลาที่กำหนดเอง (ในหน่วยมิลลิวินาที) เช่นnotify-send --expire-time 999999999 ...
Bryce Guinta

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 หรือไม่?
Vignesh

13

นอกจากเสื้อคลุมอย่าง souravc แนะนำแล้วมันไม่มีวิธีที่ดีเลยที่จะทำสิ่งนี้ในการทุบตี คุณสามารถแฮกในแบบของคุณด้วยกับดัก 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(ย้ายไปที่จุดเริ่มต้นของบรรทัด) วางสตริง "mesure" ที่ด้านหน้าของคำสั่งที่คุณป้อนCtrlm(ดำเนินการ)

ดังนั้นคุณจะได้รับฟังก์ชั่นการเติมข้อมูลอัตโนมัติและENTERคำสั่งแยกต่างหากสำหรับการวัดเวลาในขณะที่ยังคงวัตถุประสงค์เดิมของฟังก์ชั่นที่สองที่ฉันโพสต์ร้องไว้

ณ ตอนนี้นี่คือเนื้อหาของ~/.inputrcไฟล์ของฉัน:

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

และนี่คือเนื้อหาของ.bashrc(หมายเหตุฉันไม่ได้ใช้ทุบตีในตลอดกาล - ฉันใช้ mksh เป็นเปลือกของฉันดังนั้นนั่นคือสิ่งที่คุณเห็นในโพสต์ต้นฉบับฟังก์ชั่นยังคงเหมือนเดิม)

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 ด้วย ผมได้ทดสอบด้วยและส่วนใหญ่กับsudo lsof ping -c20 google.com
Sergiy Kolodyazhnyy

3

ฉันเพิ่งสร้างเครื่องมือที่ให้บริการตามวัตถุประสงค์นี้ มันสามารถเรียกใช้เป็น wrapper หรือโดยอัตโนมัติด้วยการรวมเปลือก ตรวจสอบที่นี่: http://ntfy.rtfd.io

วิธีติดตั้ง:

sudo pip install ntfy

วิธีใช้เป็น wrapper:

ntfy done sleep 3

หากต้องการรับการแจ้งเตือนโดยอัตโนมัติให้เพิ่มสิ่งนี้ใน.bashrcหรือ.zshrc:

eval "$(ntfy shell-integration)"

1

สคริปต์ของคุณทำงานได้ค่อนข้างดีเพียงให้แน่ใจว่าคุณรวมบรรทัด'shebang' ( #!/bin/bash) คนอื่น ๆ ที่#!/bin/bashจะกล่าวถึงที่นี่แต่ส่วนใหญ่#!/bin/bashทำงานได้ดีสำหรับสคริปต์ทุบตี Unix จำเป็นต้องใช้ล่ามสคริปต์เพื่อให้ทราบว่าเป็นสคริปต์ประเภทใด

ดูเหมือนว่าจะทำงานเป็นสคริปต์ทดสอบ:

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

คุณสามารถแก้ไข Bash เพื่อใช้งานฟังก์ชั่น wrapper ที่คุณต้องการ

หากคุณมีแนวโน้มที่จะทำการปรับเปลี่ยนเชลล์แบบอินเทอร์แอคทีฟจำนวนมากคุณอาจพิจารณาเปลี่ยนเป็นเชลล์ที่แฮ็กได้ภายในเช่น eshell ซึ่งสร้างขึ้นโดยใช้ 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


ทำไมคำตอบของฉันถูกลดระดับลง ฉันต้องการที่จะรู้ว่าฉันผิดพลาดในคำตอบ
Rumesh

ฉันไม่ได้ลงคะแนน แต่ฉันจะบอกคุณว่ามีอะไรผิดปกติ: ประการแรกต้องพิมพ์คำสั่งเพิ่มเติม ฉันระบุไว้ในความโปรดปรานของฉันโดยเฉพาะฉันไม่ต้องการทำเช่นนั้น ประการที่สองทำไม Calc? $((2+2))เป็นทุบตีในตัวไม่ต้องการโปรแกรมเพิ่มเติมใด ๆ ประการที่สาม: มันไม่ทำงานกับคำสั่งที่มีช่องว่าง tl; dr: มันเลวร้ายยิ่งกว่าคำตอบอายุ 1 ปีอื่น ๆ
Galgalesh

ดี ..... เวลาเริ่มต้นและเวลาสิ้นสุดจะแตกต่างกันใช่มั้ย แม้แต่คำสั่งสั้น ๆ ที่มีความยาว 1 วินาที
Sergiy Kolodyazhnyy มี. ค.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.