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

aio*_*obe 65 notification bash

每当运行超过 15 秒的命令在交互式 shell 中完成时,我都希望收到桌面通知。

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

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

在 bash 中完成此任务的最佳方法是什么?

sou*_* c. 34

据我了解你想要一个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"
}
Run Code Online (Sandbox Code Playgroud)

将此函数复制到您的~/.bashrc和源~/.bashrc中,

. ~/.bashrc
Run Code Online (Sandbox Code Playgroud)

用途

wrapper <your_command>
Run Code Online (Sandbox Code Playgroud)

如果超过 15 秒,您将收到描述命令及其执行时间的桌面通知。

例子

wrapper sudo apt-get update
Run Code Online (Sandbox Code Playgroud)

桌面硝化的屏幕截图

  • 我想避免在我输入的每个命令前写上 `wrapper`。 (4认同)
  • `命令; alert` 实际上比 `wrapper command` 短 :-) (3认同)
  • @aioobe 你可以使用更短的函数名,甚至可以是一个字母。但是包装器以这种方式工作。 (2认同)

pre*_*ise 31

~/.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$//'\'')"'
Run Code Online (Sandbox Code Playgroud)

可用于通知命令执行完成。

用法:

$ the_command; alert
Run Code Online (Sandbox Code Playgroud)

例如

$ sudo apt-get update; alert
Run Code Online (Sandbox Code Playgroud)

快照1

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

  • 很高兴知道。有没有办法在我输入的每个命令之后附加警报(并且只有当命令花费超过 15 秒时才会发出警报)? (3认同)

sil*_*sil 27

您需要https://launchpad.net/undistract-me(可从 Ubuntu 存档中安装sudo apt-get install undistract-me),它可以完全满足您的要求,包括自动工作(也就是说,无需记住添加一些额外的东西来潜在的长时间——运行命令)。

  • 你需要在`.bashrc`中添加以下两行:`. /usr/share/undistract-me/long-running.bash``notify_when_long_running_commands_finish_install`。这似乎是一个错误:https://github.com/jml/undistract-me/issues/23 (4认同)

gei*_*rha 13

除了像 souravc 建议的包装器之外,在 bash 中没有任何好的方法可以做到这一点。您可以使用 DEBUG 陷阱和 PROMPT_COMMAND 绕过它。每当您运行命令时都会触发调试陷阱,并且在写入提示之前运行 PROMPT_COMMAND。

所以东西~/.bashrc变得像

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

这是一个 hack,所以如果您遇到奇怪的副作用,请不要感到惊讶。


Ser*_*nyy 5

编辑

TL;DR.inputrc.bashrc . 像往常一样运行命令,输入,但不是ENTER按您在中指定的快捷方式.inputrc

在这个问题上悬赏的人说:

“所有现有的答案都需要在命令后输入一个额外的命令。我想要一个自动执行此操作的答案。”

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

因此,您可以获得自动完成功能和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


}
Run Code Online (Sandbox Code Playgroud)

原帖

这是我的想法 - 在.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


}
Run Code Online (Sandbox Code Playgroud)

在这里,我将输出重定向到/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


}
Run Code Online (Sandbox Code Playgroud)

这是第一个和第二个版本的截图,按顺序

第一个版本,没有输出 在此处输入图片说明

第二个版本,带输出 在此处输入图片说明