Nếu bạn có thể lưu tệp dấu thời gian giữa các lần chạy, bạn có thể kiểm tra ngày của tệp thay vì chỉ dựa vào ngày hiện tại.
Nếu lệnh find của bạn hỗ trợ các giá trị phân đoạn cho -mtime
(hoặc có -mmin
) ( GNU find có cả hai , POSIX dường như không yêu cầu ), bạn có thể 'điều tiết' các công việc cron bằng tìm và chạm .
Hoặc, nếu bạn có lệnh stat hỗ trợ hiển thị ngày của tệp dưới dạng giây giây kể từ epoch '(ví dụ: stat từ Gnu coreutils , cũng như các cách triển khai khác), bạn có thể tự so sánh bằng cách sử dụng ngày , stat và toán tử so sánh của shell (cùng với cảm ứng để cập nhật tệp dấu thời gian). Bạn cũng có thể sử dụng ls thay vì stat nếu nó có thể thực hiện định dạng (ví dụ: ls từ GNU fileutils ).
Dưới đây là chương trình Perl (tôi gọi nó n-hours-ago
) cập nhật tệp dấu thời gian và thoát thành công nếu dấu thời gian ban đầu đủ cũ. Văn bản sử dụng của nó cho thấy làm thế nào để sử dụng nó trong một mục crontab để điều tiết một công việc cron. Nó cũng mô tả các điều chỉnh cho các khoản tiết kiệm ánh sáng ban ngày của Cameron và cách xử lý các dấu thời gian 'trễ' từ các lần chạy trước.
#!/usr/bin/perl
use warnings;
use strict;
sub usage {
printf STDERR <<EOU, $0;
usage: %s <hours> <file>
If entry at pathname <file> was modified at least <hours> hours
ago, update its modification time and exit with an exit code of
0. Otherwise exit with a non-zero exit code.
This command can be used to throttle crontab entries to periods
that are not directly supported by cron.
34 2 * * * /path/to/n-hours-ago 502.9 /path/to/timestamp && command
If the period between checks is more than one "day", you might
want to decrease your <hours> by 1 to account for short "days"
due "daylight savings". As long as you only attempt to run it at
most once an hour the adjustment will not affect your schedule.
If there is a chance that the last successful run might have
been launched later "than usual" (maybe due to high system
load), you might want to decrease your <hours> a bit more.
Subtract 0.1 to account for up to 6m delay. Subtract 0.02 to
account for up to 1m12s delay. If you want "every other day" you
might use <hours> of 47.9 or 47.98 instead of 48.
You will want to combine the two reductions to accomodate the
situation where the previous successful run was delayed a bit,
it occured before a "jump forward" event, and the current date
is after the "jump forward" event.
EOU
}
if (@ARGV != 2) { usage; die "incorrect number of arguments" }
my $hours = shift;
my $file = shift;
if (-e $file) {
exit 1 if ((-M $file) * 24 < $hours);
} else {
open my $fh, '>', $file or die "unable to create $file";
close $fh;
}
utime undef, undef, $file or die "unable to update timestamp of $file";
exit 0;