我参考了以下链接,解决方案有效。
当您手动删除文件时,上述解决方案有效。但我有一个删除文件的 python 脚本(自动过程)。有时,当脚本尝试删除文件时,我会收到“设备或资源繁忙错误”。因此,我的脚本失败了。我不知道如何使用我的 python 脚本解决这个问题。
编辑: 该脚本从日志服务器下载日志文件。然后这些文件由我的脚本处理。处理完成后,脚本将删除这些日志文件。我不认为设计有什么问题。
确切的错误:
OSError: [Errno 16] Device or resource busy: '/home/johndoe/qwerty/.nfs000000000471494300000944'
答案1
这些文件是 NFS 占位符:
/home/johndoe/qwerty/.nfs000000000471494300000944
一些背景
在典型的 UNIX 文件系统中,当前正在使用和打开的文件可以被删除,但其内容实际上不会消失,直到它的最后一个文件句柄被关闭。您可以使用如下代码来查看此操作:
$ ps -ef >/tmp/temporaryfile
$ ls -l /tmp/temporaryfile
-rw-r--r-- 1 roaima roaima 6758 Mar 2 14:02 /tmp/temporaryfile
$ ( sleep 60 ; cat ) </tmp/temporaryfile &
[1] 4864
$ rm /tmp/temporaryfile
$ ls -l /tmp/temporaryfile
ls: cannot access /tmp/temporaryfile: No such file or directory
$ fg # Wait for the rest of the minute
( sleep 60; cat ) < /tmp/temporaryfile
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 09:44 ? 00:00:02 init [2]
root 2 0 0 09:44 ? 00:00:00 [kthreadd]
root 3 2 0 09:44 ? 00:00:00 [ksoftirqd/0]
root 5 2 0 09:44 ? 00:00:00 [kworker/0:0H]
...
roaima 4857 4786 0 14:02 pts/1 00:00:00 -bash
roaima 4858 4857 0 14:02 pts/1 00:00:00 ps -ef
(请注意,这与 Microsoft Windows 相反,在 Microsoft Windows 中,文件打开时无法删除。)
解释
NFS 服务器上的文件可能有一个或多个客户端访问它。 NFS 本身(大部分)是无状态的,因此需要模拟允许打开的文件即使在被删除后也可以被访问的功能。
通过将文件从文件系统中的位置删除但将其保留为名称以 . 开头的文件来处理模拟.nfs
。当最后一个读取器/写入器关闭该文件的文件句柄时,它将被正确地从文件系统中删除。
这是一个实际的例子:
$ ps -ef > /var/autofs/net/nfsserver/tmp/temporaryfile
$ ls -l /var/autofs/net/nfsserver/tmp/temporaryfile
-rw-r--r-- 1 roaima roaima 6766 Mar 2 14:14 /var/autofs/net/nfsserver/tmp/temporaryfile
$ ( sleep 60 ; cat ) </var/autofs/net/nfsserver/tmp/temporaryfile &
[1] 4987
$ rm /var/autofs/net/nfsserver/tmp/temporaryfile
$ ls -l /var/autofs/net/nfsserver/tmp/temporaryfile
ls: cannot access /var/autofs/net/nfsserver/tmp/temporaryfile: No such file or directory
$ ls -lA /var/autofs/net/nfsserver/tmp/
total 8
-rw-r--r-- 1 roaima roaima 6766 Mar 2 14:14 .nfs000000000100000300000001
$ rm /var/autofs/net/nfsserver/tmp/.nfs000000000100000300000001
rm: cannot remove ‘/var/autofs/net/nfsserver/tmp/.nfs000000000100000300000001’: Device or resource busy
$ fg # Wait for the rest of the minute
( sleep 60; cat ) < /var/autofs/net/nfsserver/tmp/temporaryfile
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 09:44 ? 00:00:02 init [2]
root 2 0 0 09:44 ? 00:00:00 [kthreadd]
root 3 2 0 09:44 ? 00:00:01 [ksoftirqd/0]
...
roaima 4983 4712 0 14:14 pts/0 00:00:00 ps -ef
推论
您应该忽略 NFS 装载上名称以.nfs
.此外,您的代码需要应对在所有这些文件实际上消失之前无法删除远程目录的可能性。
NFS 对于应用程序来说并不像人们希望的那样透明。
评论
日志文件仍然打开的原因可能是远程系统上的记录器进程仍在使用它们。通常,解决方法是循环日志文件,仅下载和删除以前的日志文件,将当前日志文件保留在文件系统中以供记录器进程使用。
诸如此类的实用程序logrotate
使用特定的配置元素来处理此问题,例如delaycompress
(尝试)确保日志文件在仍在使用时不会被压缩。 (/etc/logrotate.d/apache2
至少请参阅 Debian 系统上的示例。)