我想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
缺点是在这个版本中您不需要自己执行命令,而只是获得标准通知。为了显式执行命令并无限期地监视文件/目录,可以使用类似的方法(使用-q
uiet 模式):
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") &
如果终端的原始设置包含tostop
thenecho
将在尝试写入时触发 SIGTTOU。预先运行stty -tostop
以确保设置允许echo
打印到终端:
stty -tostop; (watch -g cat tmp >/dev/null 2>&1 && echo "changed") &
请注意,其他进程可能会自行配置终端,因此它们可能会产生干扰。