当前位置: 首页>>技术问答>>正文


长时间运行命令完成时的桌面通知

, ,

问题描述

每当一个运行时间超过15秒的命令在交互式shell中完成时,我想要一个桌面通知。

换句话说,我希望所有命令都包含在这样的东西中

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

什么是在bash中实现这一目标的最佳方法?

最佳解决方案

您需要https://launchpad.net/undistract-me(可以从带有sudo apt-get install undistract-me的Ubuntu存档中安装),它可以满足您的要求,包括自动工作(即,无需记住为潜在的long-running命令添加额外内容)。

次佳解决方案

据我所知,你想要一个wrapper。并且您希望通过它使用命令,以便在命令的运行时间超过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秒,您将获得描述命令及其执行时间的desktop-notification。

wrapper sudo apt-get update

bash,notification,ubuntu

第三种解决方案

~/.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

bash,notification,ubuntu

您可以根据自己的需要和愿望自定义别名。

第四种方案

除了像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)'

这是一个黑客,所以如果你遇到奇怪的side-effects,不要感到惊讶。

第五种方案

编辑

长话短说:在.inputrc中创建自动完成快捷方式,并在.bashrc中运行。像往常一样运行命令,键入,但不是ENTER,而是按.inputrc中指定的快捷方式

在这个问题上放置赏金的人说:

“All of the existing answers require typing an additional command after the command. I want an answer that does this automatically.”

在研究这个问题的解决方案时,我偶然发现了来自stackexchange的this问题,它允许将Ctrl J绑定到一系列命令:Ctrl a(移至行首),将”mesure”字符串放在您输入的命令前面,Ctrl m(执行)

因此,你获得了auto-completion的功能和单独的ENTER命令来测量时间,同时坚持我发布的第二个功能的原始目的。

截至目前,这是我的~/.inputrc文件的内容:

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

这里是.bashrc的内容(注意,我没有永远使用bash – 我使用mksh作为我的shell,因此这就是你在原帖中看到的。功能仍然是相同的)

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但是要查看输出,也可以重定向到文件。

一个更好的方法,恕我直言,是将时间输出发送到您的主文件夹中的某个文件(这样您就不会使用时间文件污染您的系统,并且始终知道在哪里查看)。这是第二个版本

function measure () 
{

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

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

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

fi


}

这是第一版和第二版的截图,按顺序排列

第一个版本,没有输出

bash,notification,ubuntu

第二个版本,带输出

bash,notification,ubuntu

第六种方案

我最近建立了一个用于此目的的工具。它既可以作为包装器运行,也可以通过shell集成自动运行。在这里查看:http://ntfy.rtfd.io

要安装它:

sudo pip install ntfy

要将它用作包装器:

ntfy done sleep 3

要自动收到通知,请将其添加到.bashrc.zshrc

eval "$(ntfy shell-integration)"

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/1719.html,未经允许,请勿转载。