Keep running command until output differs from previous run in Bash
From man 1 watch
:
-g
,--chgexit
Exit when the output of command changes.
watch
is not required by POSIX but it's quite common anyway. In Debian or Ubuntu it's in the procps
package along with kill
and ps
(and few other tools).
Example:
watch -g -n 5 'date +%H:%M'
This should do the trick - explanations inline:
#!/usr/bin/env bash
# Exit if any errors occur or any undefined variables are dereferenced
set -o errexit -o nounset
# Store the outputs in a separate directory
output_directory="$(mktemp --directory)"
last_output_file="${output_directory}/last"
current_output_file="${output_directory}/current"
touch "$current_output_file"
ln --symbolic "$current_output_file" "$last_output_file"
# The count is just here to show that we always run at least twice, and that
# after that we run the command a random number of times.
count=0
while true
do
echo "$((++count))"
# This is our command; it prints 0 or 1 randomly
if [[ "$RANDOM" -gt 16383 ]]
then
echo 0 > "$current_output_file"
else
echo 1 > "$current_output_file"
fi
# Abort the loop when the files differ
if ! diff --brief "$last_output_file" "$current_output_file"
then
break
fi
# Shunt the current output to the last
mv "$current_output_file" "$last_output_file"
done
There are probably simpler ways to do this, but it has a couple useful features:
- It avoids creating any extraneous files, such as using
mktemp
for every output. - By starting with the last output file being a symbolic link to the current output file we guarantee that the first
diff
command sees two identical files. This avoids duplicating the command we're testing for, at the expense of one extradiff
execution.