在Linux中将文件内容复制到新文件中

在Linux中将文件内容复制到新文件中,linux,Linux,我想知道如何将文件(server.log)的所有内容复制到新文件中,并使用Linux命令从原始文件中删除这些内容。事实上,要做到这一点很容易。但我实际上想确保在该操作中不会有内容更新。下面的Linux命令可以实现我想要的功能,但我必须确保在command1-command2执行之间server.log中没有任何更改 command1: #cp server.log serverNew.log command2: #truncate -l 0 server.log 不复制,重新命名(使用mv)

我想知道如何将文件(server.log)的所有内容复制到新文件中,并使用Linux命令从原始文件中删除这些内容。事实上,要做到这一点很容易。但我实际上想确保在该操作中不会有内容更新。下面的Linux命令可以实现我想要的功能,但我必须确保在command1-command2执行之间server.log中没有任何更改

command1: #cp server.log serverNew.log 
command2: #truncate -l 0 server.log

不复制,重新命名(使用
mv
)。重命名在文件系统级别是原子级的,因此任何使用旧名称编写文件的应用程序都不会发生冲突。

之后,您可以使用touch命令确保

command3: #touch server.log

您可以同时使用这些命令:
cp oldFile newFile;目录“”>>旧文件

cp
复制您的文件。第二个命令在第一个命令之后执行,用于覆盖原始文件

显然,如果您的“程序”(或脚本)将在将旧文件内容复制到新文件后运行,则无需使用第二个命令以write方式打开文件(而不是write和append
此外,对于
>
重定向,您必须验证
noclobber
选项是否设置为“off”(1)

我将使用专门为此目的构建的工具,而不是使用特定的解决方案

看一看。您可以直接使用该命令,也可以在cron作业中设置该命令

它支持压缩、每次旋转后运行命令、根据大小或时间旋转等

根据您在下面的评论,我假设您对这些选项感兴趣:

postrotate/endscript

日志文件旋转后,(使用
/bin/sh
)执行
postrotate
endscript
之间的行(这两行必须单独出现在行上)。这些指令只能出现在日志文件定义中通常,日志文件的绝对路径作为第一个参数传递给脚本。如果指定了
SharedScript
,则整个模式将传递给脚本。另请参见
预旋转
。有关错误处理,请参见
SharedScript
NoSharedScript

prerotate/endscript


在日志文件旋转之前,仅当日志实际旋转时,才会执行
prerotate
endscript
之间的行(这两行必须单独出现在行上)。这些指令只能出现在日志文件定义中通常,日志文件的绝对路径作为第一个参数传递给脚本。如果指定了
SharedScript
,则整个模式将传递给脚本。另请参见
postrotate
。有关错误处理,请参见
SharedScript
NoSharedScript

下面是一个简单的C应用程序,它(可能)会执行您想要的操作:

#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);
}
#包括
#包括
#包括
void main(整型argc,字符**argv)
{
如果(argc!=2)
出口(1);
FILE*fi=fopen(argv[1],“rb+”;
文件*fo=fopen(argv[2],“wb”);
如果(fi!=NULL&&fo!=NULL&&flock(fi,LOCK_EX)==0)
{
while(feof(fi)==0)
{
char*buf=malloc(4096);
int=0;
面包=fread(buf,14096,fi);
fwrite(buf,1,bRead,fo);
}
弗雷温(fi);
fputc(10,fi);
羊群(fi、LOCK_UN);
fclose(fi);
fclose(fo);
}
其他出口(1);
出口(0);
}
像这样调用:
/a.out oldfile newfile

警告:我还没有实际测试过此代码,请确保在将其用于任何重要工作之前进行一些测试


或者,您也可以尝试使用shell工具
flock

我必须保留orojinal文件,因为该文件由应用程序(如Glassfish)使用。若我删除它,甚至创建一个同名的新文件,应用程序将不会写入其输出。
cat'>>oldFile
不会向oldFile追加任何内容
cat(显然)无法打开无名文件,因此没有附加任何内容<代码>echo-n'>oldFile
将清空oldFile。我必须保留原始文件,因为该文件由一个应用程序(如Glassfish)使用。若我删除或移动它,甚至创建一个同名的新的,应用程序不会写入它的output@mmc18这意味着应用程序仍然打开该文件,并且很可能它会继续附加到
mv
ed文件,即使名称不同(在这种情况下,您在原始问题中的方法也可能无法按预期工作)。如果您确实想避免丢失任何条目,则必须关闭应用程序,然后根据需要触摸
mv
/
cp
/
然后重新启动应用程序。或者使用
logrotate
按计划自动为您执行此操作。您是对的。应该使用专用工具。我的解决方案是#cp server.log serverNew.log;truncate-s 0 server.log但在创建serverNew.log文件后,我将对其进行压缩和签名。那么,logrotate是否为我提供了新创建的文件的名称,或者它是否执行了其他操作,如压缩和运行其他脚本?它有许多选项。只需查看手册页上的
logrotate
man logrotate
。添加在我的回答中为您提供一些信息。:)