Przerwij wszystkie twarde linki w folderze


10

Mam folder, który zawiera pewną liczbę plików, które mają twarde linki (w tym samym folderze lub gdzie indziej), i chcę usunąć link do tych plików, aby stały się niezależne, a zmiany ich zawartości nie wpłyną na żadne inny plik (liczba linków zmienia się na 1).

Poniżej podaję rozwiązanie, które zasadniczo kopiuje każdy twardy link do innej lokalizacji, a następnie przenosi go z powrotem na miejsce.

Jednak ta metoda wydaje się dość prymitywna i podatna na błędy, więc chciałbym wiedzieć, czy istnieje jakieś polecenie, które usunie dla mnie link do pliku.

Surowa odpowiedź:

Znajdź pliki z twardymi linkami ( Edytuj : Aby również znaleźć gniazda itp., Które mają twarde linki , użyj find -not -type d -links +1):

find      -type f -links +1 # files only
find -not -type d -links +1 # files, sockets etc.

Prymitywna metoda usunięcia twardego linku z pliku (skopiuj go do innej lokalizacji i przenieś go z powrotem): Edytuj: Jak powiedziała Celada, najlepiej wykonać cp -p poniżej, aby uniknąć utraty znaczników czasu i uprawnień. Edycja: Utwórz katalog tymczasowy i skopiuj do pliku znajdującego się pod nim, zamiast nadpisywać plik tymczasowy, minimalizuje to ryzyko nadpisania niektórych danych, choć mvpolecenie jest nadal ryzykowne (dzięki @Tobu). Edycja: Spróbuj utworzyć katalog tymczasowy w tym samym systemie plików (@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

Tak więc, aby cofnąć hardlink wszystkich twardych linków ( Edytuj : zmieniono -type fna -not -type d, patrz wyżej):

find -not -type d -links +1 -print0 | xargs -0 unhardlink.sh

Nie uważałbym tego za „prymitywne”. Jedynym sposobem, aby uzyskać to szybciej, jest prawdopodobnie wykonanie pewnej sztuczki przy wywołaniu systemowym sendfile () oraz odłączenie pliku open source i przepisanie celu w miejscu. Szczerze mówiąc, nie jest to warte wysiłku.
— Matthew Ife

Przez „surowe” mam na myśli to, że na przykład, kiedy uruchomiłem to polecenie za pomocą cp -iprzełącznika, wypluł na mnie kilka wiadomości z pytaniem, czy powinien zastąpić ./fileXXXXXX( $tempplik), mimo że plik tmp powinien podać unikalne nazwy plików, więc musi być czymś w rodzaju wyścigu lub czymkolwiek, a wraz z nim ryzyko utraty niektórych danych.
— Suzanne Dupéron

1
To normalne, że plik istnieje, właśnie utworzyłeś go przy pomocy tempfile (nb: przestarzałe na rzecz mktemp, ale nie to spowodowało twój problem).
— Tobu

1
Twoja unhardlink.shpowinny stworzyć katalog tymczasowy wewnątrz tego samego katalogu, który zawiera plik, który należy unhardlinked. W przeciwnym razie wywołanie rekurencyjne może się powtórzyć w innym systemie plików, co może spowodować przeniesienie elementów poza granice systemu plików, ponieważ katalog tymczasowy znajduje się w bieżącym katalogu roboczym. Myślę, że "$(dirname "$i")/hardlink-XXXXXX"zamiast tego możesz podać argument jako argument dla mktemp.
— Mikko Rantalainen

1
@MikkoRantalainen Bardzo dziękuję, zaktualizowano! Zauważ, że jeśli system plików jest jakimś związkiem lub systemem fuseplików, może faktycznie zostać wysłany path/to/hardlink-XXXna inny fizyczny nośnik pamięci niż path/to/original-file, ale niewiele można na to poradzić.
— Suzanne Dupéron

Odpowiedzi:


9

W skrypcie jest miejsce na ulepszenia, na przykład dodanie -popcji do cppolecenia, dzięki czemu uprawnienia i znaczniki czasu zostaną zachowane podczas operacji odhaczania łącza, a można dodać obsługę błędów, aby plik tymczasowy został usunięty w przypadku błędu, ale podstawowa idea Twojego rozwiązania jest jedyna, która zadziała. Aby usunąć link do pliku, musisz go skopiować, a następnie przenieść kopię z powrotem do oryginalnej nazwy. Nie ma „mniej surowego” rozwiązania, które ma warunki wyścigu na wypadek, gdyby inny proces uzyskiwał dostęp do pliku w tym samym czasie.


Rzeczywiście, zawsze używam cp -a podczas kopiowania rzeczy, aby zachować wszystko, ponownie tworzyć i kopiować dowiązania symboliczne jako dowiązania symboliczne. Nie wiem, dlaczego tym razem zapomniałem, ale po zobaczeniu twojej odpowiedzi zrozumiałem, że zepsułem wszystkie moje znaczniki czasu i musiałem (raczej boleśnie) odzyskać je z kopii zapasowej.
— Suzanne Dupéron,

5

Jeśli chcesz spalić miejsce na dysku i masz stosunkowo nowoczesną wersję tar(np. Tego, co jest na Ubuntu 10.04 i CentOS 6), możesz grać z tą --hard-dereferenceopcją.

Coś jak:

$ cd /path/to/directory
$ ls -l *
bar:
total 12
-rw-rw-r-- 2 cjc cjc 2 May  6 19:07 1
-rw-rw-r-- 2 cjc cjc 2 May  6 19:07 2
-rw-rw-r-- 1 cjc cjc 2 May  6 19:07 3

foo:
total 12
-rw-rw-r-- 2 cjc cjc 3 May  6 19:07 1
-rw-rw-r-- 2 cjc cjc 2 May  6 19:07 2
-rw-rw-r-- 1 cjc cjc 2 May  6 19:07 4

(gdzie biec ln foo/[12] bar)

$ tar cvf /tmp/dereferencing.tar --hard-dereference .
$ tar xvf /tmp/dereferencing.tar
$ ls -l *
bar:
total 12
-rw-rw-r-- 1 cjc cjc 2 May  6 19:07 1
-rw-rw-r-- 1 cjc cjc 2 May  6 19:07 2
-rw-rw-r-- 1 cjc cjc 2 May  6 19:07 3

foo:
total 12
-rw-rw-r-- 1 cjc cjc 3 May  6 19:07 1
-rw-rw-r-- 1 cjc cjc 2 May  6 19:07 2
-rw-rw-r-- 1 cjc cjc 2 May  6 19:07 4

Ze strony podręcznika:

   --hard-dereference
          follow hard links; archive and dump the files they refer to

Podejrzewam, że niewiele smoły nie da rady. Niezła poprawka.
— Joseph Kern

Zapomniałem wspomnieć, że nie mam wystarczającej ilości miejsca na dysku, aby wszystko skopiować. Zasadniczo twoja metoda jest taka sama cp -a --no-preserve=links /path/to/folder /path/to/copy && rm -rf /path/to/folder && mv /path/to/copy /path/to/folder, jeśli się nie mylę. Sądzę jednak, że twoja metoda byłaby bardziej wydajna, ponieważ tar wymagałby mniejszej liczby operacji na dysku, a więc mniej kłopotów. To samo można osiągnąć za pomocą rsync, z jeszcze niższą wydajnością niż metoda cp :).
— Suzanne Dupéron,

1
Aby uniknąć używania dużej ilości dodatkowego dysku, może być możliwe uruchomienie czegoś takiego, tar cvf - --hard-dereference . | tar xf -ale może istnieć sytuacja wyścigu, która spowoduje wybuch rzeczy. Nie próbowałem tego i jestem w tej chwili trochę niechętny.
— cjc
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.