Reputation: 10147
I would like to know how to copy all content of a file (server.log) to a new file and removing the content from original file by using Linux commands. Actually it is easy to to that. But I actually want to be sure there will not be content update within that operations. Following Linux commands do what i want, but I have to be sure there is no change in server.log between command1-command2 execution.
command1: #cp server.log serverNew.log
command2: #truncate -l 0 server.log
Upvotes: 3
Views: 12472
Reputation: 16111
Here is a simple C application that will (probably) do what you want:
#include <stdlib.h>
#include <stdio.h>
#include <sys/file.h>
void main (int argc, char** argv)
{
if (argc != 2)
exit(1);
FILE* fi = fopen(argv[1], "rb+");
FILE* fo = fopen(argv[2], "wb");
if (fi != NULL && fo != NULL && flock(fi, LOCK_EX) == 0)
{
while (feof(fi) == 0)
{
char* buf = malloc(4096);
int bRead = 0;
bRead = fread(buf, 1, 4096, fi);
fwrite(buf, 1, bRead, fo);
}
frewind(fi);
fputc(10, fi);
flock(fi, LOCK_UN);
fclose(fi);
fclose(fo);
}
else exit(1);
exit(0);
}
Call like: ./a.out oldfile newfile
Warning: I have not actually tested this code, be sure to do some testing before you use this for any kind of important work.
Alternatively, you could also try something with the shell-tool flock
: http://linux.die.net/man/1/flock
Upvotes: 0
Reputation: 5475
I would use a tool especially built for this purpose instead of using some ad hoc solution.
Take a look at logrotate. You can use the command directly or set it up in a cron job.
It's supports compression, running command after each rotation, rotating based on size or time etc...
Based on your comment below I assume you are interested in these options:
postrotate/endscript
The lines between postrotate
and endscript
(both of which must appear on lines by themselves) are executed (using /bin/sh
) after the log file is rotated. These directives may only appear inside a log file definition. Normally, the absolute path to the log file is passed as first argument to the script. If sharedscripts
is specified, whole pattern is passed to the script. See also prerotate
. See sharedscripts
and nosharedscripts
for error handling.
prerotate/endscript
The lines between prerotate
and endscript
(both of which must appear on lines by themselves) are executed (using /bin/sh
) before the log file is rotated and only if the log will actually be rotated. These directives may only appear inside a log file definition. Normally, the absolute path to the log file is passed as first argument to the script. If sharedscripts
is specified, whole pattern is passed to the script. See also postrotate
. See sharedscripts
and nosharedscripts
for error handling.
Upvotes: 4
Reputation: 29932
You can use those command in tandem: cp oldFile newFile; cat '' >> oldFile
cp
copy your file. The second command, that is executed afert the first, is use for overwriting the original file
Obviously if your "program" (or script) that will run once you copy the content of old file into new one, open the file in write (and not in write and append) the second command isn't necessary.
Moreover for >>
redirection, you have to verify that the noclobber
option is setted to "off" (1)
Upvotes: 0
Reputation: 1136
After that you can use touch command to make sure
command3: #touch server.log
Upvotes: 0
Reputation: 400159
Don't copy, do a rename (with mv
). The rename is atomic at the file system level, so any application writing a file with the old name will not collide.
Upvotes: 0