Terminal: Continuously check mail, but not too often
I have a command check_mail
that checks my mail. I have it configured to run hourly because I don't want to hammer the server too much.
But, sometimes I am really at the edge of my seat for a response from someone, so I run it more often since I don't want to wait up to an hour.
Surely there's a way in the terminal to say "run this command every minute"?
I know about watch
. But my mail script can take some time to complete. So for example if I make it run every 120 secs, and one time the script takes 130 secs, I definitely do not want watch
to create a second parallel instance of the mail checker.
Does watch
already take care of this, or is there some other tool I can use?
1 answer
The following users marked this post as Works for me:
User | Comment | Date |
---|---|---|
matthewsnyder | (no comment) | Jul 19, 2024 at 16:25 |
watch
will let you do what you want, yes. This can be easily demonstrated by running watch
with a brief-running command and a delay, such as:
$ watch -n2 'date; sleep 5'
and observing that the printed time increments in approximately 7-second steps (the two seconds between watch
executions plus the five seconds sleep inside the command that is being executed). It's only approximately because neither watch
nor sleep
are precision tools and you might hit a whole-second boundary, but broadly this will update the time displayed once per seven seconds.
Another way is to run your script inside a loop:
$ while sleep 7; do date; done
or alternatively
$ while date; do sleep 7; done
or perhaps more idiomatically
$ while true; do date; sleep 7; done
(Which one of those to use depends on whether you want a delay before or after the first invocation. The first will sleep
first, then run date
; the second will do the opposite; the third is explicit about the order of operations. Once running, the observable effect is the same.)
Also, if your check_mail
script can't be allowed to run more than one instance at any one time, it should prevent that. An easy way to do so is to use the program flock
with -en
(exclusive lock, non-blocking mode) on a relevant file. (An alternative way of expressing -n
is -w 0
to specify a zero wait time to acquire the lock if the lock cannot be acquired immediately. See flock(1) for more details.) As an example, if your check_mail
script ends up calling fetchmail
naming a configuration file using the latter's -f
/--fetchmailrc
parameter, you might do something like:
fetchmailrc=~/.fetchmailrc.d/some-account.conf
while true; do
flock -en $fetchmailrc fetchmail -f $fetchmailrc
sleep 120
done
In case the lock cannot be acquired by flock
, execution will then fall through to the next command more or less immediately instead of fetchmail
being invoked. The above would attempt again to invoke fetchmail 120 seconds after the previous attempt finishes, whether or not the earlier attempt was successful.
0 comment threads