Saya memiliki folder yang berisi sejumlah file tertentu yang memiliki tautan keras (di folder yang sama atau di tempat lain), dan saya ingin menghapus tautan-tautan file-file ini, sehingga mereka menjadi independen, dan perubahan pada isinya tidak akan memengaruhi apa pun. file lain (jumlah tautannya menjadi 1).
Di bawah, saya memberikan solusi yang pada dasarnya menyalin setiap tautan keras ke lokasi lain, lalu memindahkannya kembali ke tempatnya.
Namun metode ini tampaknya agak kasar dan rawan kesalahan, jadi saya ingin tahu jika ada beberapa perintah yang akan menghapus hard-file untuk saya.
Jawaban kasar:
Temukan file yang memiliki tautan keras ( Edit : Untuk juga menemukan soket dll. Yang memiliki tautan keras , gunakan find -not -type d -links +1
):
find -type f -links +1 # files only
find -not -type d -links +1 # files, sockets etc.
Metode kasar untuk menghapus tautan file (menyalinnya ke lokasi lain, dan memindahkannya kembali):
Edit: Seperti kata Celada, yang terbaik adalah melakukan cp -p di bawah ini, untuk menghindari kehilangan stempel waktu dan izin. Sunting: Buat direktori sementara dan salin ke file di bawahnya, alih-alih menimpa file temp, itu meminimalkan risiko untuk menimpa beberapa data, meskipun mv
perintahnya masih berisiko (terima kasih @Tobu). Sunting: Cobalah untuk membuat direktori sementara di sistem file yang sama (@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
Jadi, untuk menghapus tautan semua tautan keras ( Edit : diubah -type f
menjadi -not -type d
, lihat di atas):
find -not -type d -links +1 -print0 | xargs -0 unhardlink.sh
cp -i
sakelar, itu meludahi saya beberapa pesan yang menanyakan apakah harus menimpa./fileXXXXXX
($temp
file), meskipun tmpfile harus memberikan nama file yang unik, jadi harus ada menjadi semacam kondisi ras atau apa pun, dan dengan itu risiko kehilangan beberapa data.unhardlink.sh
harus membuat direktori sementara di dalam direktori yang sama yang berisi file yang perlu dihapus tautannya. Kalau tidak, panggilan rekursif Anda dapat berulang di dalam sistem file lain dan Anda akhirnya memindahkan barang-barang di atas batas-batas filesystem karena direktori sementara Anda ada di direktori saat ini. Saya kira Anda bisa memberikan"$(dirname "$i")/hardlink-XXXXXX"
argumen sebagai mktemp sebagai gantinya.fuse
filesystem, itu mungkin sebenarnya dikirimpath/to/hardlink-XXX
ke media penyimpanan fisik yang berbeda daripath/to/original-file
, tetapi tidak ada banyak yang bisa dilakukan tentang itu.Jawaban:
Ada ruang untuk perbaikan dalam skrip Anda, misalnya menambahkan
-p
opsi kecp
perintah sehingga izin dan stempel waktu akan dipertahankan di seluruh operasi pembatalan tautan, dan Anda bisa menambahkan beberapa penanganan kesalahan sehingga file temp dihapus jika terjadi kesalahan, tetapi ide dasar dari solusi Anda adalah satu-satunya yang akan berhasil. Untuk menghapus tautan file, Anda harus menyalinnya dan kemudian memindahkan salinannya kembali ke nama aslinya. Tidak ada solusi "kurang mentah", dan solusi ini memiliki kondisi balapan jika proses lain mengakses file pada saat yang sama.sumber
Jika Anda ingin membakar ruang disk, dan Anda memiliki versi yang relatif modern
tar
(misalnya, apa yang ada di Ubuntu 10,04 dan CentOS 6), Anda dapat bermain dengan--hard-dereference
opsi tersebut.Sesuatu seperti:
(tempat saya berlari
ln foo/[12] bar
)Dari halaman manual:
sumber
cp -a --no-preserve=links /path/to/folder /path/to/copy && rm -rf /path/to/folder && mv /path/to/copy /path/to/folder
, jika saya tidak salah. Saya kira metode Anda akan lebih efisien, karena tar akan melibatkan lebih sedikit pencarian disk, jadi kurang meronta-ronta. Seseorang dapat mencapai hal yang sama dengan rsync, dengan kinerja yang bahkan lebih rendah daripada metode cp :).tar cvf - --hard-dereference . | tar xf -
tetapi mungkin ada kondisi balapan yang akan menyebabkan hal-hal meledak. Saya belum mencobanya, dan saya agak enggan melakukannya saat ini.