解決策 1:
あなたの最善の策は、 lsof
を使用することです ファイルが何らかのプロセスによって開かれたかどうかを判断するには:
# lsof -f -- /var/log/syslog
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsyslogd 1520 syslog 1w REG 252,2 72692 16719 /var/log/syslog
書き込み中かどうかは簡単にはわかりませんが、書き込み中の場合は開いている必要があります。
編集:提案された解決策を実装しようとするのではなく、ここで実際の問題を解決しましょう!
rsync を使用してファイルを転送します:
○ → rsync -e ssh remote:big.tar.gz .
この方法では、ファイルは既存のファイルの上にコピーされるのではなく、一時ファイル (.big.tar.gz.XXXXXX
) 転送が完了するまで、その後所定の位置に移動します。
解決策 2:
ファイルの名前変更はアトミック操作であるため、アップロード後に名前を変更するのは簡単でエレガントで、エラーが発生しにくいです。私が考えることができる別のアプローチは、 lsof | grep filename.tar.gz
を使用することです ファイルが別のプロセスによってアクセスされているかどうかを確認します。
解決策 3:
少し古いですが、ほとんどの回答は質問の要点を完全に見逃しています:
<ブロック引用>しかし、最初にコマンドラインでファイルが完全かどうかを判断する簡単な方法があるかどうかを調べてみようと思いました...
一般的に、ありません。それを判断するのに十分な情報がありません。
ファイルが閉じていると判断するため ファイルが全体であるかどうかを判断することと同じではありません .たとえば、転送の途中で接続が失われた場合、ファイルは「クローズ」されます。
@Alexの答えだけがこれを正しくしました。そして、彼でさえ lsof
を使用して落ちました
ファイルが完全に転送されたかどうかを判断するには、さらにデータが必要です。例:
<ブロック引用>
私が考えていた代替案の 1 つは、ファイルを別のファイル拡張子 (.tar.gz.part
など) としてコピーすることでした。 )、その後 .tar.gz
に名前が変更されました 転送が完了した後。
これは、ファイルが完全かつ正常に転送されたことを伝えるのに最適な方法です。同じファイルシステム内にいる限り、ファイルをあるディレクトリから別のディレクトリに移動することもできます。または、送信者に空の filename.done
を送信してもらいます
しかし、すべてのメソッドは、転送が正常に完了したことを何らかの方法で通知する送信者に依存する必要があります。送信者だけがその情報を持っているからです.
一部のファイル形式 (PDF など) には、ファイルが完全かどうかを判断できるデータが含まれています。しかし、それを見つけるには、ファイル全体を開いて読む必要があります。
lsof
ファイルが開かれていないことを通知するだけで、理由は通知されません もう開いていません。また、ファイルのサイズも教えてくれません。
解決策 4:
これを行う最善の方法は、incron (「inotify cron システム」) を使用することです。ディレクトリにinotifyウォッチを設定すると、ファイル操作が通知されます。この場合、dir で close_write を監視する必要があります。これにより、書き込み後にファイルが閉じられると、コマンドを実行できるようになります。
解決策 5:
lsof は、ファイルが開かれているモードを検出できるようです:
lsof -f -- a_file
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
cat 52391 bob 1w REG 1,2 15 19545007 a_file
1wって書いてあるのわかる?これは、ファイル記述子番号が 1 で、モードが w または書き込みであることを意味します。