Linux
如何以事務方式複製文件?
我想將一個文件從 A 複製到 B,它可能位於不同的文件系統上。
還有一些額外的要求:
- 副本全有或全無,崩潰時沒有部分或損壞的文件 B 留在原處;
- 不要覆蓋現有文件 B;
- 不要與同一命令的並發執行競爭,最多一個可以成功。
我認為這很接近:
cp A B.part && \ ln B B.part && \ rm B.part
但是如果 B.part 存在(即使使用 -n 標誌), cp 也會違反 3. 隨後 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)。有沒有辦法檢測這樣的文件系統?
其他一些相關但不完全相同的問題:
有沒有辦法將文件和目錄從 tempfs 原子移動到 eMMC 上的 ext4 分區
https://rcrowley.org/2010/01/06/things-unix-can-do-atomically.html
rsync
做這項工作。預設情況下會創建一個臨時文件O_EXCL
(僅在使用 時才禁用--inplace
),然後renamed
覆蓋目標文件。用於--ignore-existing
不覆蓋 B(如果存在)。在實踐中,我在 ext4、zfs 甚至 NFS 掛載上從未遇到過任何問題。
別擔心,
noclobber
是標準功能。