Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Terminal: Continuously check mail, but not too often

+0
−0

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?

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

1 answer

+3
−0

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.

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.

1 comment thread

Blocking concurrent runs (1 comment)

Sign up to answer this question »