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
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.