長時間実行されているコマンドが完了したときのデスクトップ通知


59

たとえば、15秒以上実行されたコマンドが対話型シェルで終了するたびにデスクトップ通知を受け取りたいです。

つまり、すべてのコマンドを次のようにラップしたい

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

これをbashで達成する最良の方法は何ですか?




なぜ今「インタラクティブシェル」を追加したのですか?元の投稿のコンテキストに1年以上存在していた既存の回答の一部が無効になる場合があります。対話型シェル専用のソリューションが必要な場合は、これに関する別の質問をすることを検討してください。
セルギーKolodyazhnyy

「インタラクティブシェル」の部分は、編集前の最初のコメントで明確になりました。質問を編集してコメントを削除しただけです。また、質問に投稿された3行はスクリプトに適しています。
aioobe

回答:


24

あなたは欲しいhttps://launchpad.net/undistract-me(とUbuntuのアーカイブからインストールをsudo apt-get install undistract-me使用すると、潜在的に長期に余分な何かを追加することを忘れないようにせずに、(つまり、自動的に作業を含め、ために求めている正確に何をしています)コマンドの実行)。


1
動作していないようです。私はそれをインストールし、システムを再起動し、でテストしましたsleep 30が、通知はありません。
ガルガレシュ

4
以下に2行を追加する必要があります.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

使用法

wrapper <your_command>

15秒以上かかる場合は、コマンドとその実行時間を説明するデスクトップ通知が表示されます。

wrapper sudo apt-get update

デスクトップ編集のスクリーンショット


1
"$@"ではありません$@。大きな違い。
ガイラ14年

4
私がwrapper入力するすべてのコマンドの前に書くことは避けたいです。
aioobe 14年

2
@aioobeでは、文字であっても短い関数名を使用できます。しかし、ラッパーはこの方法で機能します。
souravc 14年

3
command; alertより短い実際にあるwrapper command:-)
aioobe

1
notify-send長期間失効させたくない場合は、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 14年

私の.bashrcに既に追加されている奇妙なことですが、ubuntuのデフォルトですか?
ヴィニッシュ

13

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)'

これはハックですので、これで奇妙な副作用に遭遇しても驚かないでください。


4

編集

TL; DR:でオートコンプリートショートカットを作成し.inputrc、で機能し.bashrc ます。通常どおりコマンドを実行し、入力しますが、代わりにENTERで指定したショートカットを押します.inputrc

この質問に賞金をかけた人は言った:

「既存の回答はすべて、コマンドの後に追加のコマンドを入力する必要があります。これを自動的に行う回答が必要です。」

この問題の解決策を研究している間、私はスタックエクスチェンジからこの質問に出くわしました。これはCtrlJ一連のコマンドへのバインドを許可します:(Ctrla行の先頭に移動Ctrlm

したがってENTER、以下に掲載する2番目の機能の本来の目的を維持しながら、オートコンプリートの機能と時間を測定するための個別のコマンドを取得します。

現在、私の~/.inputrcファイルの内容は次のとおりです。

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

そして、ここに内容があります.bashrc(注、私は永遠にbashを使用していません-私はシェルとして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は、時間の出力をホームフォルダー内のファイルに送信することです(タイムファイルでシステムを汚染せず、常にどこを参照するかを常に把握できるようにします)。これがその2番目のバージョンです

function measure () 
{

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

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

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

fi


}

そして、この順序での最初と2番目のバージョンのスクリーンショットです

最初のバージョン、出力なし ここに画像の説明を入力してください

2番目のバージョン、出力あり ここに画像の説明を入力してください


ところで、sudoコマンドでも動作します。私はそれをsudo lsof主にでテストしましたping -c20 google.com
セルギーKolodyazhnyy

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/bashUnix 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最初に実行して、実行可能であることを確認してください。



-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$@実行することにより、任意のコマンドでこれを行うこともでき./script commandます。


なぜ私の答えはダウン投票されたのですか?私は答えでどこが悪かったのか知りたい
ルメシュ

ダウン投票しませんでしたが、何が問題なのかを説明します。まず、追加のコマンドを入力する必要があります。私は、賞金で具体的に私はそれをしたくないと述べました。第二に、なぜcalc?$((2+2))bashビルトインであり、追加のプログラムを必要としません。3番目:スペースを含むコマンドでは機能しません。tl; dr:他の1歳の回答よりも悪い
Galgalesh

まあ.....開始時刻と終了時刻は常に異なりますよね?でも、短いコマンドのために、それは長い1secondある
Sergiy Kolodyazhnyy
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.