每当在交互式外壳中运行了超过15秒的命令时,我都希望收到桌面通知。
换句话说,我希望所有命令都被包装成这样
start=$(date +%s);
ORIGINAL_COMMAND;
[ $(($(date +%s) - start)) -le 15 ] || notify-send "Long running command finished"
在bash中完成此操作的最佳方法是什么?
每当在交互式外壳中运行了超过15秒的命令时,我都希望收到桌面通知。
换句话说,我希望所有命令都被包装成这样
start=$(date +%s);
ORIGINAL_COMMAND;
[ $(($(date +%s) - start)) -le 15 ] || notify-send "Long running command finished"
在bash中完成此操作的最佳方法是什么?
Answers:
您想要https://launchpad.net/undistract-me(可从Ubuntu归档文件安装,具有sudo apt-get install undistract-me
),它可以精确地满足您的要求,包括自动工作(也就是说,无需记住为可能很长的时间添加额外的内容,运行命令)。
sleep 30
,但没有任何通知。
.bashrc
:. /usr/share/undistract-me/long-running.bash
notify_when_long_running_commands_finish_install
。看来是个错误:github.com/jml/undistract-me/issues/23
据我了解,你想要一个包装纸。并且您想通过它使用命令,以便如果命令的运行时间超过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
"$@"
不是$@
。巨大差距。
wrapper
在我键入的每个命令之前编写代码。
command; alert
实际上比短wrapper command
:-)
notify-send
长时间过期,请给通知发送自定义超时(以毫秒为单位)。例如notify-send --expire-time 999999999 ...
其中~/.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
您可以根据自己的需要和愿望自定义别名。
除了像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)'
这是一个技巧,因此如果您遇到奇怪的副作用,请不要感到惊讶。
编辑
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
}
原始帖子
这是我的想法-在中使用函数.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
}
这是第一和第二版本的屏幕截图,按顺序
第一版,无输出
第二版,带输出
sudo lsof
并且大多数使用进行了测试ping -c20 google.com
。
我最近构建了一个用于此目的的工具。它既可以作为包装程序运行,也可以与Shell集成一起自动运行。在这里查看:http : //ntfy.rtfd.io
要安装它:
sudo pip install ntfy
要将其用作包装器:
ntfy done sleep 3
要自动获取通知,请将其添加到您的.bashrc
或中.zshrc
:
eval "$(ntfy shell-integration)"
您的脚本运行良好,只需确保包含“ shebang” (#!/bin/bash
)行即可。这里#!/bin/bash
要提到的其他脚本,但是在大多数情况下,对于Unix bash脚本来说效果很好。脚本解释器需要它,因此它知道脚本的类型。#!/bin/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
它以确保它是可执行的。
您可以修改Bash以实现所需的包装器功能。
如果您打算对交互式外壳进行许多此类修改,则可以考虑切换到使用emacs elisp构建并具有所有存储的可定制性的内在可破解外壳,例如eshell。
http://www.masteringemacs.org/articles/2010/12/13/complete-guide-mastering-eshell/
您也可以使用简单的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
。
$((2+2))
是内置的bash,不需要任何其他程序。第三:不适用于带空格的命令。TL;博士:它比其他1岁的答案更糟