代码之家  ›  专栏  ›  技术社区  ›  hawkeye

将DOS中程序的stdout导出到每日滚动日志文件?

  •  1
  • hawkeye  · 技术社区  · 14 年前

    我有一个DOS程序,由一个命令脚本启动,它将我想跟踪的大量数据转储到一个日志文件中。我可以很容易地将它传送到一个文件中-但我需要一个滚动日志文件。

    是否有一种简单的方法将输出传输到将生成每日滚动日志文件的程序?(即每天创建一个新文件)

    1 回复  |  直到 10 年前
        1
  •  0
  •   paxdiablo    14 年前

    如果不控制正在运行的程序的源代码,一种可能是使用另一个脚本,作为计划任务运行,关闭程序,移动日志文件,然后重新启动程序。把这个安排在午夜左右。

    如果你 不能 定期关闭程序,另一种可能性是开发一个过滤程序,它将采用标准输入,并根据今天的日期将其发送到日志文件。该程序可以检测日期更改,并在文件超过午夜边界时关闭/重新打开文件。

    然后将原始程序的输出通过这个过滤器进行传输。顺便说一下,这是真管道。您当前所做的不是技术上的管道而是重定向(管道指向进程,重定向指向文件)。

    伪代码是这样的:

    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 )它运行,每13秒生成一次日期,十次:

    #!/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 函数使用日边界(请参见注释)。