shell - keep writing to the same file[name] even i

2019-06-13 20:16发布

There's a process, which should not be interrupted, and I need to capture the stdout from it.

  prg > debug.log

I can't quite modify the way the process outputs its data, though I'm free to wrap its launch as I see fit. Background, piping the output to other commands, etc, that's all a fair game. The process, once started, must run till the end of times (and can't be blocked, say, waiting for a fifo to be emptied). The writing isn't very fast, and the file can be cut at arbitrary place, if it exceeds predefined size.

Now, the problem is the log would grow to fill all available space, and so it must be rotated, oldest instances deleted/overwritten. And now there's the problem...

If I do

   mv debug.log debug.log.1

the file debug.log vanishes forever while debug.log.1 keeps growing.

If I do

   cp debug.log debug.log.1
   rm debug.log

the file debug.log.1 doesn't grow, but debug.log vanishes forever, and all consecutive output from the program is lost.

Is there some way to make the stdout redirect behave like typical log writing - if the file vanished, got renamed or such, create it again?

(this is all working under busybox, so lightweight solutions are preferred.)

2条回答
爷、活的狠高调
2楼-- · 2019-06-13 21:02

You may use the split command or any other command which reopens a new file

prg | split --numeric-suffixes --lines=100 debug.log.

The reason is, that the redirected file output is sent to a file handle, not the file name. So the process has to close the file handle and open a new one.

You may use rotatelogs to do it in Apache HTTPD style, if you like:

http://httpd.apache.org/docs/2.2/programs/rotatelogs.html

In bash style, you can use a script:

fn='debug.log'
prg | while IFS='' read in; do
    if ...; then # time or number of lines read or filesize or ...
        i=$((i+1))
        mv "$file" "$fn.$i" # rename the file
        > "$file" # make it empty
    fi
    echo "$in" >> "$file" # fill the file again
done
查看更多
Viruses.
3楼-- · 2019-06-13 21:13

If the application in question holds the log file open all the time and cannot be told to close and re-open the log file (as many applications can) then the only option I can think of is to truncate the file in place.

Something like this:

cp debug.log debug.log.1
: > debug.log
查看更多
登录 后发表回答