ファイルをトランザクション方式でコピーする方法は?

ファイルをトランザクション方式でコピーする方法は?

別のファイルシステムにある可能性があるAからBにファイルをコピーしたいです。

いくつかの追加要件があります。

  1. コピーは全部または全部であり、競合時にファイルBの一部または破損した部分を残しません。
  2. 既存のファイルBを上書きしないでください。
  3. 同じコマンドの同時実行と競合しないでください。最大1つだけ成功できます。

私はこれが近いと思います:

cp A B.part && \
ln B B.part && \
rm B.part

ただし、3. B.partが存在すると(-nフラグがあっても)違反し、cpは失敗しません。その後 1. 他のプロセスが cp を「勝ち」、所定の場所にリンクされたファイルが不完全な場合、失敗することがあります。 B.partが無関係なファイルである可能性がありますが、他の隠された名前を試さずにこの場合失敗することを嬉しく思います。

私はbash noclobberが役に立つと思います。これはまったく機能しますか? bashバージョンを必要としない方法はありますか?

#!/usr/bin/env bash
set -o noclobber
cat A > B.part && \
ln B.part B && \
rm B.part

フォローアップを実行すると、一部のファイルシステムがとにかく失敗することがわかります(NFS)。これらのファイルシステムを検出する方法はありますか?

関連しているが同じではない他の質問:

ファイルシステム間のおおよその原子移動?

私のfsにmv原子がありますか?

eMMCのtempfsからext4パーティションにファイルとディレクトリをアトミックに移動する方法はありますか?

https://rcrowley.org/2010/01/06/things-unix-can-do-atomically.html

ベストアンサー1

rsyncタスクを実行します。デフォルトでは、一時ファイルが作成されO_EXCL(使用している場合にのみ無効--inplace)、renamedターゲットファイルが上書きされます。--ignore-existingBがある場合は上書きしないために使用されます。

実際、私はext4、zfs、さらにはNFSマウントでも問題が発生したことがありません。

おすすめ記事