書き込み中のファイルを除いて、フォルダー内のすべてのファイルをコピーするにはどうすればよいですか?

書き込み中のファイルを除いて、フォルダー内のすべてのファイルをコピーするにはどうすればよいですか?

複数のファイルをフォルダにダウンロードするにdownloadingHTTP についてbashスクリプトはダウンロードしたファイルを処理することを目的としており、ダウンロードしたファイルを別のフォルダにコピーしようとしました。

find /folder/downloading -type f -exec mv '{}' /folder/downloaded \;

しかし、これはまだ完了していないファイルもコピーします。-mmin +5コマンドに追加して、転送を古いファイルに限定しようとしました。書き込み中のファイルをそのままにして、ダウンロードしたファイルのみを転送する効率的なコマンドは何ですか?

答え1

あまり効率的ではありませんが、次のようにすることもできます。

find /folder/downloading -type f -exec sh -c '
  for file do
    lsof -F a "$file" | grep -q w || mv "$file" /folder/downloaded
  done' sh {} +

つまり、実行する前に、ファイルがファイルのリストにライト アクセス モードでリストされていないことを確認waます。lsofmv

Linux ベースのオペレーティング システムに典型的に見られる の実装には関数 (書き込み用に開かれているファイルを確認する) がありますpsmiscが、残念ながら、対応するプロセスを強制終了する場合にのみ機能します。ただし、何もしない疑似シグナル 0 を使用することで、引き続き使用できるようです。fuser-w-k

find /folder/downloading -type f -exec sh -c '
  for file do
    fuser -s -w -k -0 "$file"  || mv "$file" /folder/downloaded
  done' sh {} +

どのプロセスが移動を妨げているかを確認する場合は、を削除します-s(または に置き換えます)。-v

これらのコマンドをスーパーユーザーとして実行していない場合は、自分のプロセスに関する情報のみが取得されることに注意してください。ファイルをダウンロードするプロセスが別のユーザーとして実行されている場合、そのプロセスは検出されません。

また、ファイルを別のファイル システムに移動しない限り、ファイルを移動しても、現在ファイルに書き込んでいるプロセスがファイルへの書き込みを完了するのを妨げることはないことに注意してください。

しかし、その後に何をするように設計されているかにもよりますが、書き込みを終えた後にファイルがなくなってしまった場合、混乱してしまうかもしれません(例えば、ダウンロード後にファイルの属性を変更したい場合など)。ないファイル記述子を介して ( や などchmod()fchmod()ファイルutimes()記述子経由では実行できない)。

関連情報