方便的腳本來減少硬連結計數?
我正在將一個大文件集從具有高
_PC_LINK_MAX
(每個 inode 的最大硬連結數)的文件系統轉換到較低的文件系統。特別是,我正在搞亂 Amazon EFS,它最多有 175 個,如此處所述。
因此,我希望輸入是一組連結計數高達 250 的文件重新調整,以便 inode 被拆分,因此每個連結最多為 100 個。
有沒有一個聰明的呼叫,比如說,
hardlink
可以做到這一點?或者可能是一個選項,rsync -aH
或者可能cp -a
有幫助?…否則,一些黑客是為了…
情況很棘手。想像一下最大鍊接是 5 個,而您有 12 個文件
a01
要a12
全部硬連結在一起。您需要拆分a01..a05
anda06..a10
,a11..a12
wherea06
和a07
etc 仍然是硬連結在一起的,但不是 toa01
。這是一個 bash 腳本
rsync
,它在我的系統上的範例源目錄 (src=/usr/libexec/git-core/
) 上執行,該目錄有 110 個硬連結。它通過函式max
在目標目錄中模擬最大數量的 50 個連結 ( ) 。在實際情況下,您只需忽略太多連結錯誤,而不使用此功能。realdest``sim
在初始正常 rsync(有錯誤)之後,通過使用創建失去文件列表,
rsync -ni
將函式中的文件名提取calctodo
到/tmp/todo
.然後有一個循環,我們
rsync
失去了文件,再次忽略了太多的連結錯誤(如果您2*175
在原始目錄中有多個連結,則會出現這種錯誤)。成功創建的文件相互之間是硬連結的。計算出新的失去文件列表。重複此操作,直到沒有更多文件為止。src=/usr/libexec/git-core/ realdest=/tmp/realdest #rm -fr "$realdest" max=50 sim(){ find ${1?} -links +$max | sed "1,${max}d" | xargs --no-run-if-empty rm } calctodo(){ sed -n '/^hf/{ s/[^ ]* //; s/ =>.*//; p }' >/tmp/todo } rsync -aHR "$src" "$realdest"; sim "$realdest" rsync -niaHR "$src" "$realdest" | calctodo while [ -s /tmp/todo ] do mv /tmp/todo /tmp/todo.old rsync -aHR --files-from=/tmp/todo.old / "$realdest"; sim "$realdest" rsync -niaHR --files-from=/tmp/todo.old / "$realdest" | calctodo done
如果您的文件名帶有“=>”、換行符等,您可能需要修改它。
請注意,您可以通過以下方式找到文件系統支持的最大鍊接數
getconf LINK_MAX /some/directory