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