【问题标题】:copy file content into new file in Linux在 Linux 中将文件内容复制到新文件中
【发布时间】:2012-06-29 13:05:12
【问题描述】:

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

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

【问题讨论】:

    标签: linux


    【解决方案1】:

    我会使用专门为此目的构建的工具,而不是使用一些临时解决方案。

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

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

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

    postrotate/endscript

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

    prerotate/endscript

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

    【讨论】:

    • 你是对的。应使用专用工具。我的解决方案是 # cp server.log serverNew.log; truncate -s 0 server.log 但在创建 serverNew.log 文件后,我将对其进行压缩并签名。
    • 那么 logrotate 是给我新创建的文件的名称,还是执行其他操作,例如压缩和运行附加脚本?
    • 它有很多选项。只需查看 logrotateman logrotate 的手册页即可。
    • 在我的回答中为您添加了一些信息。 :)
    【解决方案2】:

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

    【讨论】:

    • 我必须保留原始文件,因为应用程序使用了这个文件,比如 Glassfish。如果我删除或移动它甚至创建一个同名的新应用程序,应用程序不会写入其输出
    • @mmc18 这意味着应用程序仍然打开文件,它很可能会继续附加到 mved 文件,即使名称不同(在这种情况下,您的方法在原始问题也可能无法按预期工作)。如果您确实想避免丢失任何条目,则必须关闭应用程序,然后根据需要mv/cp/touch,然后重新启动应用程序。或使用logrotate 自动为您安排时间。
    【解决方案3】:

    之后你可以使用touch命令确认

    command3: #touch server.log
    

    【讨论】:

      【解决方案4】:

      您可以同时使用这些命令:cp oldFile newFile; cat '' >> oldFile
      cp 复制您的文件。在第一个命令之后执行的第二个命令用于覆盖原始文件

      显然,如果您将旧文件的内容复制到新文件中后将运行的“程序”(或脚本),则以写入方式(而不是写入方式并追加)第二个方式打开文件命令不是必需的。
      此外,对于>> 重定向,您必须验证noclobber 选项是否设置为“关闭”(1)

      【讨论】:

      • 我必须保留 orojinal 文件,因为应用程序使用了这个文件,比如 Glassfish。如果我删除它甚至创建一个同名的新应用程序,应用程序不会写入它的输出。
      • cat '' >> oldFile 不向 oldFile 附加任何内容。 cat(显然)无法打开无名文件,因此没有附加任何内容。 echo -n '' > oldFile 将清空 oldFile。
      【解决方案5】:

      这是一个简单的 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);
      }
      

      致电:./a.out oldfile newfile

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

      或者,您也可以尝试使用 shell-tool flock: http://linux.die.net/man/1/flock

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-02
        • 1970-01-01
        • 2014-04-30
        • 2013-10-08
        • 2015-11-09
        相关资源
        最近更新 更多