如何使后台“watch”在更改时执行命令

如何使后台“watch”在更改时执行命令

我想watch在某些命令和文件(例如w)上使用,让它在后台运行并通知我任何更改。我尝试过以下方法:

(watch -g cat tmp && echo "changed") &

但是,当我更改 的内容时,什么也没有发生tmp,并且watch只有当我将其放在前台时才会退出fg

有没有办法watch在后台运行并通知我更改?

答案1

一种简单的方法是通过inotifywait监视器-m模式,即永久运行而不是在第一个记录事件后退出。指定-e要监视的文件/目录修改等通风口 - 或不显示所有事件,例如打开、访问、写入等。man inotifywait有关可能事件的更多信息,请参阅 参考资料。

$inotifywait -m -e modify tmp &
$echo 1 >> tmp
tmp MODIFY

缺点是在这个版本中您不需要自己执行命令,而只是获得标准通知。为了显式执行命令并无限期地监视文件/目录,可以使用类似的方法(使用-quiet 模式):

while ((1)) ; do \
   inotifywait -q -e modify tmp && echo "tmp was changed" \
done &

答案2

watch不是为您想做的事情而设计的。

在某些时候watch尝试重新配置终端。处于后台它得到 SIGTTOU并停止。整个工作都会收到 SIGTTOU 信号。

在具有作业控制的交互式 shell 中,您可以在jobs稍后调用时看到这一点。在zsh你会看到一个注释suspended (tty output)jobs在其他 shell 中可能不会提供如此多的信息。

在我的测试中,我需要将 stdout 和 stderr 重定向远离终端:

(watch -g cat tmp >/dev/null 2>&1 && echo "changed") &

如果终端的原始设置包含tostopthenecho将在尝试写入时触发 SIGTTOU。预先运行stty -tostop以确保设置允许echo打印到终端:

stty -tostop; (watch -g cat tmp >/dev/null 2>&1 && echo "changed") &

请注意,其他进程可能会自行配置终端,因此它们可能会产生干扰。

相关内容