有没有一种手表只有在收到信号后才会刷新?

有没有一种手表只有在收到信号后才会刷新?

我有一个窗口运行着一个有点昂贵的watch git log ...咒语——足够昂贵,以至于它实际上看起来更像是这样,watch -n30 timeout 10 git log ...这样它就不会过度损害我的系统。

然而,这不需要每 30 秒运行一次。它只需要在我运行 git 命令时运行。如果watch支持它,我可以在我想要更新它时发送 SIGUSR1 信号watch,这将节省大量计算能力。

我怎样才能实现这个目标?

答案1

这可以是一个 shell 脚本。您需要它来:

  1. 一直什么也不做
  2. 对信号运行钩子

这样的陷阱trap 'git log' SIGUSR1就会完成2.1.可以近似模拟 sleep $aLongTime并完美完成:

tmp=`mktemp`; echo 'int main(){ pause(); return 0; }' > "$tmp";
gcc -x c "$tmp" -o pause #create a `pause` executable

那么你的 shell 脚本可以是:

echo $$ #identify self
trap 'git log' SIGUSR1 
while :; do ./pause; done

答案2

这是一个用于此目的的小型 python 2.6 程序:

import signal,sys,os

cmdString = " ".join(sys.argv[1::]).strip()

def handler(sig,frame):
        if sig == signal.SIGUSR1:
                refresh()
        elif sig == signal.SIGINT:
                print 'You pressed Ctrl+C!'
                sys.exit(0)

def refresh():
        os.system(cmdString)
        print "\n"
        signal.pause()

signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGUSR1, handler)
print('Press Ctrl+C to exit')
refresh()

答案3

这有点脏,但确实有效。

while :; do watch -n3600 git log ...; sleep 0.5; done

这依赖于手表在收到 USR1 时退出的事实。然而,每当需要信号时,就会将错误消息写入终端。抑制它2>/dev/null不起作用:它会让人watch认为它没有与终端通信,并且“用户定义的信号”消息仍然出现。

为了让你能够干净地控制循环,需要睡眠。

答案4

您可以创建一个 shell 函数并在收到特定(或多个)信号时调用它。watch是不适合这项工作的工具。当经过一定时间时它会触发。您希望不是根据时间而是根据信号触发。

下面是一个简单的 shell 脚本,演示了该功能:

#!/bin/sh

gitlog() {
  clear
  git log
}

while :; do
  trap gitlog USR1
done

exit 0

测试用kill <PID> -SIGUSR1.您仍然可以使用ctrl-终止该脚本c

相关内容