This example maintains a mirror of
code.dogmap.org. in the
./mirror. It runs under Laurent Bercot's
# 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
setuidgidchanges to the uid and gid of
mirroruser, which should be able to write to the
rw-addadds the current time and 1 second and stores the result in
rw-matchcomputes the earliest time at or after
$now1sthat matches 2:30 AM (local time), and stores the result in
$wake. (Adding 1 second in the previous step ensures that if
./doitruns in less than one second,
rw-matchwon'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
$MTAI64Nand 36 hours, and stores the result in
rw-mincomputes the earlier of
$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.)
statfilefinds the last-modified time of the file "started" and stores it in
$MTAI64Nand 1 hour, and stores the result in
rw-maxcomputes the later of
$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.)
$wakeas the next scheduled run time.
$wake. (You can make it wake up immediately at any time by sending
svc -a /service/mirror-dogmap.)
./doittouches the file "
started" to record that the job was attempted.
./doitupdates the mirror with
ftpcopyexits nonzero, the shell also exits, because of the
./doittouches the file "
finished" to record that the job completed successfully.
./doit(which is running in the same process that was originally the
./run, and cycle begins again. (If you prefer to have your services never exit during normal operation, you could have
./doitend by exec'ing