Linux

方便的腳本來減少硬連結計數?

  • September 28, 2016

我正在將一個大文件集從具有高_PC_LINK_MAX(每個 inode 的最大硬連結數)的文件系統轉換到較低的文件系統。

特別是,我正在搞亂 Amazon EFS,它最多有 175 個,如此所述。

因此,我希望輸入是一組連結計數高達 250 的文件重新調整,以便 inode 被拆分,因此每個連結最多為 100 個。

有沒有一個聰明的呼叫,比如說,hardlink 可以做到這一點?或者可能是一個選項,rsync -aH或者可能cp -a有幫助?

…否則,一些黑客是為了…

情況很棘手。想像一下最大鍊接是 5 個,而您有 12 個文件 a01a12全部硬連結在一起。您需要拆分a01..a05and a06..a10a11..a12wherea06a07etc 仍然是硬連結在一起的,但不是 to a01

這是一個 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

引用自:https://unix.stackexchange.com/questions/312717