This example maintains a mirror of code.dogmap.org. in the
directory ./mirror. It runs under Laurent Bercot's
s6
system.
# cd /service/mirror-dogmap # cat run #!/bin/sh exec 2>&1 \ s6-setuidgid mirroruser \ rw-add n d1S now1s \ rw-match \$now1s ,H=2,M=30 wake \ statfile -M finished \ rw-add \$MTAI64N d36H latest \ rw-min \$wake \$latest wake \ statfile -M started \ rw-add \$MTAI64N d1H earliest \ rw-max \$wake \$earliest wake \ sh -c ' echo "@$wake" | s6-tai64nlocal | sed "s/^/next run time: /" exec "$@"' arg0 \ rw-sleep \$wake \ ./doit # cat doit #!/bin/sh touch started && ftpcopy -x '/mirror/*' code.dogmap.org / ./mirror && touch finished
setuidgid changes to the uid and gid of
mirroruser, which should be able to write to the
./mirror directory.
rw-add adds the current time and 1 second and stores the
result in $now1s.
rw-match computes the earliest time at or after
$now1s that matches 2:30 AM (local time), and stores the
result in $wake. (Adding 1 second in the previous step
ensures that if ./doit runs in less than one second,
rw-match won't schedule it to run again immediately; we'll
schedule it for 2:30 AM the next day.)
statfile (from the
misc/fdtools package) finds the
last-modified time of the file "finished" and stores it in
$MTAI64N.
rw-add adds $MTAI64N and 36 hours, and stores
the result in $latest.
rw-min computes the earlier of $wake and
$latest, and stores the result in $wake. (This
ensures that if the job fails, or was not run for some reason, it will be
scheduled to run at most 36 hours after the last time it completed
successfully, so the mirror will not be too far out of date.)
statfile finds the last-modified time of the file
"started" and stores it in $MTAI64N.
rw-add adds $MTAI64N and 1 hour, and stores
the result in $earliest.
rw-max computes the later of $wake and
$earliest, and stores the result in $wake.
(This ensures that even if the job fails several times, it will not be
attempted more often than once an hour, to avoid swamping a clogged
network link.)
sh command logs $wake as the next
scheduled run time.
rw-sleep sleeps until $wake. (You can make
it wake up immediately at any time by sending SIGALRM via
svc -a /service/mirror-dogmap.)
./doit touches the file "started"
to record that the job was attempted.
./doit updates the mirror with ftpcopy. If
ftpcopy exits nonzero, the shell also exits, because of the
-e option.
./doit touches the file "finished" to
record that the job completed successfully.
./doit (which is running in the same process that was
originally the run script) exits. supervise
restarts ./run, and cycle begins again. (If you prefer to
have your services never exit during normal operation, you could have
./doit end by exec'ing ./run.)