次のリンクを参照して解決しました。
上記の回避策は、ファイルを手動で削除するときに機能します。しかし、ファイルを削除する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とは対照的です。)
説明する
NFSサーバー上のファイルには、そのファイルにアクセスする1つ以上のクライアントがあります。 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システムの例を参照してください。)