Uzun süre çalışan komutlar tamamlandığında masaüstü bildirimi


59

15 saniyeden uzun bir süredir çalışan bir komut etkileşimli bir kabukta tamamlandığında bir masaüstü bildirimi olmasını isterim.

Başka bir deyişle, tüm komutların böyle birşeye sarılmasını istiyorum.

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

Bunu başarmanın en iyi yolu nedir bash?




Neden şimdi "etkileşimli kabukta" ekledin? Bir yıldan fazla bir süredir orijinal gönderiniz bağlamında varolan cevaplardan bazılarını geçersiz kılabilir. Özellikle etkileşimli kabuk için bir çözüme ihtiyacınız varsa, buna başvuran ayrı bir soru sormayı düşünün.
Sergiy Kolodyazhnyy

"Etkileşimli kabuk" kısmı, düzenlemeden önceki ilk yorumda açıklığa kavuşturuldu. Ben sadece soruyu düzelttim ve yorumu kaldırdım. Ayrıca, sorulara gönderilen 3 satır bir senaryo için iyi çalışıyor.
aioobe

Yanıtlar:


24

İstediğinizi tam olarak istediğiniz şeyi yapan https://launchpad.net/undistract-me (Ubuntu arşivlerinden yüklenebilir sudo apt-get install undistract-me), otomatik olarak çalışmak da dahil (potansiyel olarak uzun süren fazladan bir şey eklemeyi hatırlamak zorunda kalmadan) çalışan komutlar).


1
Çalışıyor gibi görünmüyor. Yükledim, sistemimi yeniden başlattım ve test ettim sleep 30, ancak bildirim yok.
Galgalesh

4
Sen aşağıdaki iki satırı eklemeniz gerekir .bashrc: . /usr/share/undistract-me/long-running.bash notify_when_long_running_commands_finish_install. Bir hata gibi görünüyor: github.com/jml/undistract-me/issues/23
Ludenticus

32

Anladığım kadarıyla, bir sarıcı istiyorum . Ayrıca, komutunuzun çalışma süresi 15 saniyeden fazlaysa istediğiniz bildirimi verecek şekilde bir komut kullanmak istersiniz. Yani burada.

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

Bu işlevi şuraya kopyalayın ~/.bashrcve kaynak ~/.bashrcolarak,

. ~/.bashrc

useagenin

wrapper <your_command>

15 saniyeden uzun sürerse, komutu ve uygulama zamanını açıklayan masaüstü bildirimini alırsınız.

Örnek

wrapper sudo apt-get update

masaüstü niteleme ekran görüntüsü


1
"$@"değil $@. Büyük fark.
geirha

4
wrapperYine de yazdığım her komutun önüne yazmaktan kaçınmak istiyorum .
aioobe

2
@ aioobe, bir harf olabilir bile daha kısa bir işlev adı kullanabilirsiniz. ancak bir sarmalayıcı bu şekilde çalışır.
souravc

3
command; alertAslında wrapper command:-) daha kısadır
aioobe

1
notify-sendUzun süre boyunca sona ermesini istemiyorsanız, not -gönder özel bir zaman aşımı süresi (milisaniye cinsinden) verin. egnotify-send --expire-time 999999999 ...
Bryce Guinta

26

İçinde tanımlanmış ~/.bashrcbir diğer ad var 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$//'\'')"'

Komut işleminin tamamlandığını bildirmek için kullanılabilir.

Kullanımı:

$ the_command; alert

Örneğin

$ sudo apt-get update; alert

snap1

Takma adı gereksiniminize ve arzunuza göre özelleştirebilirsiniz.


3
Bunu bilmek güzel. Yazdığım her komuttan sonra uyarı eklemenin bir yolu var mı (ve yalnızca komutun 15 saniyeden uzun sürmesi durumunda da uyarı verilsin mi)?
aioobe

.bashrc benim zaten eklenmiş garip bir şey, ubuntu içinde varsayılan mı?
Vignesh

13

Souravc'ın önerdiği gibi bir sarıcı dışında, bunu bash yapmak için gerçekten iyi bir yol yok. Bir DEBUG tuzağı ve bir PROMPT_COMMAND ile etrafınızda dolaşabilirsiniz. Bir DEBUG tuzağı, bir komut çalıştırdığınızda tetiklenir ve PROMPT_COMMAND komut istemi yazılmadan hemen önce çalıştırılır.

Böylece şeyler ~/.bashrcgibi bir şey olur

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

Bu bir kesmek, bununla garip yan etkilerle karşılaşırsanız şaşırmayın.


4

DÜZENLE

TL; DR : içinde otomatik tamamlama kısayolu oluştur .inputrcve işlevini yap .bashrc . Komutu her zamanki gibi çalıştırın, yazın, ancak bunun yerine, ENTERbelirttiğiniz kısayola basın..inputrc

Bu soruya ödül veren kişi şöyle dedi:

"Mevcut cevapların tümü komuttan sonra ek bir komut girmenizi gerektirir. Bunu otomatik olarak yapan bir cevap istiyorum."

Bu sorunun çözümlerini araştırırken, bir komut dizisine bağlanmayı sağlayan stackexchange'ten bu soruya rastladım CtrlJ: Ctrla(satırın başına git), girdiğiniz komutun önüne "mesure" dizesini yerleştirin Ctrlm(çalıştır)

Böylece ENTER, aşağıda belirtilen ikinci işlevin orijinal amacına bakarken , otomatik tamamlama işlevselliğini ve zaman ölçmek için ayrı bir komut alırsınız .

Şu an itibariyle, işte dosyamın içeriği ~/.inputrc:

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

Ve işte .bashrc(not, sonsuza dek bash kullanmadım - kabuğum olarak mksh kullanıyorum, bu yüzden orijinal yazıda gördüğünüz budur. İşlevsellik hala aynıdır)

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


}

Orijinal Gönderi

İşte benim fikrim - bir işlev kullanın .bashrc. Temel prensip - /usr/bin/timekomutun tamamlanması için geçen süreyi ölçmek için kullanın ve 15 saniyeden uzunsa bildirim gönderin.

function measure () 
{

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

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

fi


}

Burada çıktıyı yönlendiriyorum /dev/nullama çıktıyı görüntülemek için dosyaya yönlendirme de yapılabilir.

Çok daha iyi bir yaklaşım olan IMHO, ana klasörünüzdeki bir dosyaya zamanın çıktısını göndermektir (sadece sisteminizi zaman dilimleriyle kirletmemeniz ve her zaman nereye bakacağınızı bilmeniz). İşte bu ikinci versiyon

function measure () 
{

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

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

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

fi


}

Ve işte birinci ve ikinci versiyonun ekran görüntüleri bu sırada

İlk versiyon, çıktı yok görüntü tanımını buraya girin

Çıkışlı ikinci versiyon görüntü tanımını buraya girin


Bu arada, sudo komutlarıyla da çalışıyor. İle sudo lsofve çoğunlukla ile test ettim ping -c20 google.com.
Sergiy Kolodyazhnyy

3

Geçenlerde bu amaca hizmet eden bir araç geliştirdim. Bir sarmalayıcı olarak ya da otomatik olarak kabuk entegrasyonu ile çalıştırılabilir. Burada kontrol edin: http://ntfy.rtfd.io

Yüklemek için:

sudo pip install ntfy

Bir sarıcı olarak kullanmak için:

ntfy done sleep 3

Bildirimleri otomatik olarak almak için şunu .bashrcveya şuna ekle .zshrc:

eval "$(ntfy shell-integration)"

1

Komut dosyanız oldukça iyi çalışıyor, 'shebang' ( #!/bin/bash) satırını eklediğinizden emin olun . Burada#!/bin/bash sözü edilenler , fakat çoğu zaman, Unix bash scriptleri için gayet iyi çalışıyor. Betik yorumlayıcısı tarafından istenir, böylece ne tür bir betik olduğunu bilir.#!/bin/bash

Bu bir test betiği olarak çalışıyor gibi görünüyor:

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

Bu betiği değiştirmek için, komutu echove sleepsatırları ve satırlarını koyun .

Bununla birlikte notify-send, -ibir simgeyi belirtmek için de kullanabilirsiniz :-)

Ayrıca, chmod +x /PATH/TO/FILEilk önce çalıştırarak çalıştırılabilir olduğundan emin olun .



-2

Bunu, eğer böyle bir ifade ile basit bir şekilde yapabilirsiniz.

#!/bin/bash

START=$(date +%s)

TIME=$(($START+15))

ORIGINAL_COMMAND;

END=$(date +%s)

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

Kendi değişken isimlerinizi kullanabilirsiniz.

Bunun işe yaradığını onaylayabilirim, bitirmesi çok uzun süren bir komutla test ettim, bunu yapmaz ve bildirimi uzun zaman alan biri için gelir.

Ayrıca değiştirerek herhangi bir komut ile yapabilirsiniz ORIGINAL_COMMANDile $@ve olduğu gibi komut dosyası çalıştırılırken ./script command.


Neden cevabım reddedildi?
Cevapta

Oy vermedi, ama size yanlış olanı söyleyeyim: Her şeyden önce, ek bir komut yazmanız gerekir. Ben özellikle ödülümde bunu yapmak istemediğimi belirttim. İkincisi, neden kalk? $((2+2))bir bash yerleşiktir, herhangi bir ek program gerektirmez. Üçüncüsü: boşluk içeren komutlarla çalışmıyor. dr: dr, 1 yaşındaki diğer cevaplardan daha kötü
Galgalesh

Peki ..... başlangıç ​​ve bitiş zamanları hep farklı olacak, değil mi? 1 saniye süren kısa bir emir için bile
Sergiy Kolodyazhnyy
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.