書き込まれているファイルを除くフォルダ内のすべてのファイルをコピーする方法は?


12

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

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

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


同じファイルシステムにコピーし、ダウンローダーを名前変更しないように設定する場合(ダウンロードして%.partから%に名前変更する)。次に、ダウンローダーが正常に動作している(奇妙なことは何もしない)場合、mvファイルの名前を変更()できるはずです。
ctrl-alt-delor

1
どのような処理をしようとしていますか?パイプラインを使用するなど、はるかに簡単なオプションが利用できる可能性があります。
ガーデンヘッド

回答:


11

あまり効率的ではありませんが、次のことができます。

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

これは、ファイルがでリストされていないことをチェックですw儀式aでCCESSモードlI sのトンoペンf前イレスmO vINGの。

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

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()vsなどfchmod()、またはファイル記述子を介して実行utimes()できない)。


シェルの質問:1つの例外を除いて、コードを理解していると思います。-exec実行されているsh(1つのコマンドで-c '...')、そして{} +時に、そのコマンドに複数の結果を置くためにそれを伝えます。私が理解していないのはsh、コマンドの後に別のものがある理由です。私は何が欠けていますか?
ジョー

2
@Joe、それはインラインスクリプトのに入るもの$0です。つまり、インラインスクリプトに名前付けます。この名前は<name>: fuser: command not found、たとえばエラーメッセージで使用される可能性があります。そのためsh、この場合、エラーメッセージを報告しているものを明確にするために一般的に良い選択です。インラインスクリプト)。
ステファンシャゼラス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.