Tôi có một thư mục chứa một số tệp nhất định có liên kết cứng (trong cùng thư mục hoặc ở nơi khác) và tôi muốn hủy liên kết các tệp này để chúng trở nên độc lập và thay đổi nội dung của chúng sẽ không ảnh hưởng đến tập tin khác (số liên kết của họ trở thành 1).
Dưới đây, tôi đưa ra một giải pháp về cơ bản sao chép từng liên kết cứng đến một vị trí khác, sau đó di chuyển nó trở lại vị trí.
Tuy nhiên phương pháp này có vẻ khá thô sơ và dễ bị lỗi, vì vậy tôi muốn biết liệu có một lệnh nào đó sẽ hủy liên kết một tệp cho tôi không.
Câu trả lời thô thiển:
Tìm tệp có liên kết cứng ( Chỉnh sửa : Để tìm ổ cắm, v.v. có liên kết cứng, hãy sử dụng find -not -type d -links +1
):
find -type f -links +1 # files only
find -not -type d -links +1 # files, sockets etc.
Một phương pháp thô sơ để hủy liên kết một tệp (sao chép nó sang vị trí khác và di chuyển nó trở lại):
Chỉnh sửa: Như Celada đã nói, tốt nhất nên thực hiện một cp -p bên dưới, để tránh mất dấu thời gian và quyền. Chỉnh sửa: Tạo một thư mục tạm thời và sao chép vào một tệp trong đó, thay vì ghi đè lên tệp tạm thời, nó giảm thiểu rủi ro để ghi đè lên một số dữ liệu, mặc dù mv
lệnh vẫn còn rủi ro (cảm ơn @Tobu). Chỉnh sửa: Cố gắng tạo thư mục tạm thời trong cùng hệ thống tệp (@MikkoRantalainen).
# This is unhardlink.sh
set -e
for i in "$@"; do
temp="$(mktemp -d -- "${i%/*}/hardlnk-XXXXXXXX")"
[ -e "$temp" ] && cp -ip "$i" "$temp/tempcopy" && mv "$temp/tempcopy" "$i" && rmdir "$temp"
done
Vì vậy, để bỏ liên kết cứng tất cả các liên kết cứng ( Chỉnh sửa : đã đổi -type f
thành -not -type d
, xem ở trên):
find -not -type d -links +1 -print0 | xargs -0 unhardlink.sh
cp -i
tắc, nó sẽ nhổ vào tôi một vài tin nhắn hỏi liệu nó có nên ghi đè ./fileXXXXXX
( $temp
tệp) hay không, mặc dù tmpfile nên đặt tên tệp duy nhất, do đó phải là một loại điều kiện chủng tộc hoặc bất cứ điều gì, và với nó có nguy cơ mất một số dữ liệu.
unhardlink.sh
nên tạo thư mục tạm thời trong cùng thư mục chứa tệp cần được liên kết. Mặt khác, cuộc gọi đệ quy của bạn có thể lặp lại bên trong một hệ thống tệp khác và cuối cùng bạn sẽ chuyển công cụ qua ranh giới hệ thống tệp vì thư mục tạm thời của bạn nằm trong thư mục làm việc hiện tại. Tôi đoán bạn có thể chuyển "$(dirname "$i")/hardlink-XXXXXX"
như là đối số cho mktemp thay thế.
fuse
hệ thống tệp, nó thực sự có thể gửi path/to/hardlink-XXX
đến một phương tiện lưu trữ vật lý khác path/to/original-file
, nhưng không có nhiều điều có thể làm được về điều đó.