watch is not designed for what you want to do.
At some point watch tries to reconfigure the terminal. Being in the background it gets SIGTTOU and stops. The whole job gets SIGTTOU.
In an interactive shell with job control you can see this when you invoke jobs afterwards. In zsh you would see a note suspended (tty output). jobs in other shells may not be so informative.
In my tests I needed to redirect stdout and stderr away from the terminal:
(watch -g cat tmp >/dev/null 2>&1 && echo "changed") &
If the original settings of the terminal include tostop then echo will trigger SIGTTOU when it tries to write. Run stty -tostop beforehand to make sure the settings allow echo to print to the terminal:
stty -tostop; (watch -g cat tmp >/dev/null 2>&1 && echo "changed") &
Note other processes may configure the terminal on their own, therefore they may interfere.
watchis for. watch is for repeatedly running the same command and displaying its output. you probably want to either pipe the output oftail tmpinto, e.g., an awk script that exits on the first new line, or useinotifyto monitor changes in a file. – cas Jun 23 '21 at 06:02