Ahmet Karakaya
Ahmet Karakaya

Reputation: 10147

copy file content into new file in Linux

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

Answers (5)

Cobra_Fast
Cobra_Fast

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

Eric des Courtis
Eric des Courtis

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

DonCallisto
DonCallisto

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

rad
rad

Reputation: 1136

After that you can use touch command to make sure

command3: #touch server.log

Upvotes: 0

unwind
unwind

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

Related Questions