“ cp”如何处理打开的文件?


15

我有两个单独的目录。用户将文件加载到第一个文件中。后台运行cronjob,每5分钟将文件复制到第二个目录。

如果用户尚未完成上传并且cronjob复制了文件,该怎么办?请注意,这两个目录由不同的用户拥有,cronjob是作为root执行的。


请阅读这篇文章,看看在这种情况下会发生什么:unix.stackexchange.com/questions/49299/…–
Serge

谢谢,您写的好帖子。但是我的问题更多是与cp相关,而不是一般的linux-file-handling。我虽然也许cp检查文件是否仍处于打开状态,然后等待其关闭或其他原因。
Stuffy 2012年

编号cp不会等到文件完全上载。正如我们期望的那样,网络传输速率会比仅将文件从同一主机中的一个位置复制到另一位置时要低,那么在某个时候cp它将到达当前文件结尾并停止复制。解决问题的方法可能很简单:首先,用户上传带有特殊修饰的文件名的文件(例如,以.(点字符)开头)。完成传输后,用户将其重命名为原始名称。然后,cron作业仅显示对于这些文件未开始.
塞尔

Answers:


17

cp不知道打开的文件。因此,如果第一个用户上传大文件并且cronjob(或任何其他进程)开始复制此文件,则它将仅复制已写入的文件。您可以通过这种方式来考虑- cp不管磁盘是否完整,都复制磁盘上当前的内容。否则,您将无法复制日志文件。


谢谢,这就是我想知道的!有没有简单的方法可以避免这种情况?我检查了cp手册页,但没有发现任何用处。
Stuffy 2012年

到底要做什么?要复制除打开文件以外的所有文件?我不认为还有比以创作你自己的脚本,使用这样(其他的任何简单的方法fuser+ cp这样的副本真的是非常不可靠的,不会复制在例如文本编辑器中打开的任何文件。
克日什托夫亚当斯基2012年

@Stuffy,也许在您的cronjob中,您可以使用列出打开的文件lsof?该输出将易于处理。您可以过滤要打开的文件(例如通过的一个实例cp)进行写入。
Wojtek Rzepala '10

@WojtekRzepala,我来看一下,谢谢。也许我会写一个由cronjob执行的小脚本-Stuffy
2012年

@Stuffy:请记住,如果它不是由root用户运行的(fuser当然,同样的问题),它可能并不真正可靠,因为此工具可能不会显示所有文件。
2012年

7

cp不知道还有哪些其他程序可以打开文件。中没有魔术cp。除非有令人信服的理由(令人信服的是内核需要它),否则UNIX的设计有意避免对文件施加任何形式的锁定。关于此主题,请参阅将输出重定向到文件是否对文件施加了锁定?

这种情况是很常见的,这种情况是文件由生产者生成,一旦完成,便由消费者使用。解决此问题的通常方法是让生产者写一个消费者不会寻找的临时文件,然后一旦生产者完成,将文件移到消费者可以找到的地方。移动文件(在同一文件系统上)是一项原子操作:在某些时候,对于使用者而言,文件从不存在更改为存在。

因此,完成上传后,安排您的上传作业将文件移动到其他目录。将cron作业指向这个不同的目录。


6

似乎您想执行目录同步作业。

因为-u,--update选项cp

仅在SOURCE文件比目标文件新或缺少目标文件时复制

因此,您可以添加一个cronjob,例如cp -auv SOURCEDIR/* DESTDIR它将复制修改时间已更改的文件。这意味着DESTDIR上传完成后最终将获得完整副本。

rsync可以做同样的工作。例如rsync -av SOURCEDIR/ DESTDIR

尽管应用了-a选项,但是某些指定的属性(例如,所有权)只能由超级用户保留。

有关详细信息man cp,请参见man rsync


只是提防依赖目标文件夹中的最新条目-它们可能不是完整的文件。
dubiousjim
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.