使用 BASH 和 watch 命令执行周期性任务

使用 BASH 和 watch 命令执行周期性任务

我正在尝试编写一个 BASH 脚本,目的是使用watch命令监视本地 git 存储库以了解远程分支的更改,然后执行任务。

假设脚本被调用task.sh并且看起来像:

watch -n 3000 (git remote update && git status) | \
grep -i "your branch is behind origin/" && \ 
{ "pull changes, run tests, etc." ; }

我发布的内容或多或少是我迄今为止所拥有的,但我似乎无法让最后一部分发挥作用。换句话说,当我对 git 分支进行更改时,它似乎没有启动。我能够将输出重定向watch到这样的文件watch -n 3000 ls 1>> file.txt,但是使用这种方法需要打开该文件,我认为该文件很慢并且容易出错。

我基本上想watch连续运行,直到杀死启动它的脚本,尽管如果有比watch这更好的方法也很好。

答案1

正如 DopeGhoti 提到的,cron这将是一个更好的选择。

您的示例已经有 50 分钟的间隔。如果可以接受将间隔设置为一小时,那么许多现代发行版都有一个/etc/cron.hourly目录。该目录中设置了可执行位的任何内容都将每小时运行一次(我见过的大多数实现都使用run-parts按文件名线性运行该目录中的可执行文件)。

如果必须缩短间隔,我建议/etc/cron.d。 cron 守护进程一般直接解析该目录,因此不需要设置可执行位。您可以创建一个task包含以下内容的文件。

*/30 * * * * root /path/to/task.sh

前 5 个字段分别代表分钟、小时、月份中的某一天、月份和星期几。在本例中,我们为分钟指定 30 分钟的步长值。因此,这个特定的示例将task.sh每 30 分钟、每小时、每月的每一天运行一次……您明白了。

分钟字段中超过 30 分钟的步骤值会导致在N整点后的分钟执行,其中N是分钟字段中的值。

这里奇数间隔的一种解决方案。

现在来看 bash 代码...

这没有按预期工作的原因是因为grep永远不会返回要由 评估的退出值&&。它仍在greping 的输出watch

这可以在下面的示例中看到。大括号内echo的和sleep代替watchsleep退出后grep也可以。第二个日期直到退出后才运行grep,并且可以评估退出代码。

[vagrant@localhost ~]$ date +%s; { echo a; sleep 15; } | grep 'a' && date +%s
1493875975
a
1493875990

纠正此问题的一种方法是将所有内容移至 内watch

watch -n 15 'bash -c "echo a | grep 'a' && date +%s"'

另一种选择是使用 while-true-循环。

[vagrant@localhost ~]$ while :; do echo a | grep 'a' && date +%s; sleep 15; done
a
1493875992
a
1493876007
a
1493876022
^C

相关内容