Если вы не контролируете источник для программы, которую вы запускаете, одна из возможностей состоит в том, чтобы запустить другой сценарий, запустить как запланированное задание, которое завершит работу программы, переместит файл журнала и перезапустит программу. Запланируйте это где-то около полуночи.
Если вы не можете периодически выключать программу, другой возможностью является разработка программы фильтра, которая будет принимать стандартный ввод и отправлять его в файл журнала на основе сегодняшней даты. Эта программа может обнаружить изменения даты и закрыть / открыть файл, когда он пересекает границу полуночи.
Затем направьте вывод вашей исходной программы через этот фильтр. Кстати, это правда. То, что вы в настоящее время делаете, это не техническая передача, а перенаправление (передача идет в процесс, перенаправление идет в файл).
Псевдокод будет выглядеть примерно так:
lastDate = ""
currFile = null
while not end of file on standard input:
get line from standard input
currDate = getDate()
if currDate not equal to lastDate:
if currFile not null:
close currFile
currFile = open("prefix_"+currDate+".log")
write line to currFile
if currFile not null:
close currFile
exit
В качестве подтверждения концепции приведем скрипт (qqtest.sh
), который запускается, генерируя дату каждые тринадцать секунд, десять раз:
#!/usr/bin/bash
for i in 0 1 2 3 4 5 6 7 8 9 ; do
echo $i $(date)
sleep 13
done
А вот программа фильтра C (qq.c
), которая делает то, что я описал в моем ответе выше:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
static char *getDate (void) {
static char tbuff[sizeof("yyyymmddhhmm")]; // "yyyymmdd" for date.
time_t now = time (0);
struct tm *tm = localtime (&now);
strftime (tbuff, 100, "%Y%m%d%H%M", tm); // "%Y%m%d" for date.
return tbuff;
}
int main (void) {
int ch, lastCh = '\n';
FILE *fOut = NULL;
char *currDate, *lastDate = strdup ("");
char fspec[1000];
// Just process characters until finished.
while ((ch = fgetc (stdin)) != EOF) {
// Only switch logs if first character of a line.
if (lastCh == '\n') {
// Has date changed?
currDate = getDate();
if (strcmp (currDate, lastDate) != 0) {
// Yes, close old file if there was one.
if (fOut != NULL)
fclose (fOut);
// Then store new date and open new file.
free (lastDate);
lastDate = strdup (currDate);
sprintf (fspec, "qqfile_%s.log", lastDate);
fOut = fopen (fspec, "w");
}
}
// Output character to current file then save.
fputc (ch, fOut);
lastCh = ch;
}
// Clean up memory and file handles, then exit.
free (lastDate);
if (fOut != NULL)
fclose (fOut);
return 0;
}
При выполнении:
./qqtest.sh | ./qq
создает следующие файлы.
$ cat qqfile_201005211146.log
0 Fri May 21 11:46:40 WAST 2010
1 Fri May 21 11:46:53 WAST 2010
$ cat qqfile_201005211147.log
2 Fri May 21 11:47:06 WAST 2010
3 Fri May 21 11:47:19 WAST 2010
4 Fri May 21 11:47:33 WAST 2010
5 Fri May 21 11:47:46 WAST 2010
6 Fri May 21 11:47:59 WAST 2010
$ cat qqfile_201005211148.log
7 Fri May 21 11:48:12 WAST 2010
8 Fri May 21 11:48:25 WAST 2010
9 Fri May 21 11:48:38 WAST 2010
Обратите внимание, что для переключения файлов журнала используется минутная граница. Очень просто изменить функцию getDate
, чтобы вместо нее использовать дневную границу (см. Комментарии).