biegnę
ln /a/A /b/B
Chciałbym zobaczyć w folderze a
gdzie punkty złożyć do przez ls
.
linux
filesystems
hardlink
Léo Léopold Hertz 준영
źródło
źródło
link(2)
wywołaniu systemowym nie ma sensu, który z nich jest oryginalny, a drugi link. Dlatego, jak wskazują odpowiedzi, jedynym sposobem na znalezienie wszystkich linków jestfind / -samefile /a/A
. Ponieważ jeden wpis katalogu dla i-węzła nie „wie” o innych wpisach katalogu dla tego samego i-węzła. Wszystko, co robią, to ponownie liczą i-węzeł, aby można go było usunąć, gdy jest to jego nazwiskounlink(2)ed
. (Jest to „liczba linków” nals
wyjściu).Odpowiedzi:
Możesz znaleźć numer i-węzła dla swojego pliku za pomocą
i
pokazuje liczbę referencji (liczba dowiązań twardych do konkretnego i-węzła)
po znalezieniu numeru i-węzła możesz wyszukać wszystkie pliki z tym samym i-węzłem:
pokaże nazwy plików dla i-węzła NUM w bieżącym katalogu (.)
źródło
Naprawdę nie ma dobrze zdefiniowanej odpowiedzi na twoje pytanie. W przeciwieństwie do dowiązań symbolicznych, dowiązania twarde są nie do odróżnienia od „oryginalnego pliku”.
Pozycje katalogu składają się z nazwy pliku i wskaźnika do i-węzła. Z kolei i-węzeł zawiera metadane pliku i (wskazuje na) rzeczywistą zawartość pliku). Utworzenie twardego łącza tworzy kolejną nazwę pliku + odniesienie do tego samego i-węzła. Odwołania te są jednokierunkowe (przynajmniej w typowych systemach plików) - i-węzeł zachowuje tylko liczbę odwołań. Nie ma wewnętrznego sposobu, aby dowiedzieć się, która jest „oryginalną” nazwą pliku.
Nawiasem mówiąc, właśnie dlatego wywoływane jest systemowe wywołanie w celu „usunięcia” pliku
unlink
. Po prostu usuwa twardy link. I-węzeł dołączone dane są usuwane tylko wtedy, gdy liczba referencyjna i-węzła spadnie do 0.Jedynym sposobem na znalezienie innych odniesień do danego i-węzła jest dokładne przeszukanie systemu plików i sprawdzenie, które pliki odnoszą się do danego i-węzła. Aby wykonać to sprawdzenie, możesz użyć „testu A –ef B” ze powłoki.
źródło
UNIX ma dowiązania twarde i dowiązania symboliczne (odpowiednio wykonane
"ln"
i"ln -s"
). Dowiązania symboliczne to po prostu plik, który zawiera rzeczywistą ścieżkę do innego pliku i może przechodzić przez systemy plików.Twarde linki istnieją już od najwcześniejszych dni UNIX (które i tak pamiętam, i to już od dawna). Są to dwa wpisy katalogu, które odnoszą się dokładnie do tych samych podstawowych danych. Dane w pliku są określone przez jego
inode
. Każdy plik w systemie plików wskazuje na i-węzeł, ale nie ma wymogu, aby każdy plik wskazywał na unikalny i-węzeł - stąd pochodzą twarde łącza.Ponieważ i-węzły są unikalne tylko dla danego systemu plików, istnieje ograniczenie, że dowiązania twarde muszą znajdować się w tym samym systemie plików (w przeciwieństwie do dowiązań symbolicznych). Zauważ, że w przeciwieństwie do dowiązań symbolicznych, nie ma pliku uprzywilejowanego - wszystkie są równe. Obszar danych zostanie zwolniony tylko wtedy, gdy wszystkie pliki korzystające z tego i-węzła zostaną usunięte (i wszystkie procesy również go zamkną, ale to inny problem).
Możesz użyć
"ls -i"
polecenia, aby uzyskać i-węzeł określonego pliku. Następnie możesz użyć"find <filesystemroot> -inum <inode>"
polecenia, aby znaleźć wszystkie pliki w systemie plików z danym i-węzłem.Oto skrypt, który właśnie to robi. Wywołujesz to za pomocą:
i znajdzie wszystkie pliki w tym systemie plików, które są twardymi dowiązaniami do tego pliku:
Oto skrypt.
źródło
. ./findhardlinks.bash
bycia w Zsh OS X. Moje bieżące okno na ekranie zostanie zamknięte.INUM=$(stat -c %i $1)
. RównieżNUM_LINKS=$(stat -c %h $1)
. Zobaczman stat
więcej zmiennych formatu, których możesz użyć.Pierwsza kolumna będzie reprezentować uprawnienia. Druga kolumna będzie liczbą podelementów (dla katalogów) lub liczbą ścieżek do tych samych danych (twarde linki, w tym oryginalny plik) do pliku. Na przykład:
źródło
inode
co z kolei wskazuje na zawartość dysku.Co powiesz na następującą prostszą? (Później może zastąpić powyższe długie skrypty!)
Jeśli masz konkretny plik
<THEFILENAME>
i chcesz poznać wszystkie jego łącza twarde rozproszone po katalogu<TARGETDIR>
, (może to być nawet cały system plików oznaczony przez/
)Rozszerzając logikę, jeśli chcesz poznać wszystkie pliki,
<SOURCEDIR>
które mają wiele rozpiętych linków<TARGETDIR>
:źródło
-type f
ponieważ plik może być również katalogiem..
I..
wpisy w katalogach są hardlinki. Możesz dowiedzieć się, ile podkatalogów znajduje się w katalogu na podstawie liczby linków.
. To i tak jest dyskusyjne, ponieważfind -samefile .
nadal nie wydrukuje żadnychsubdir/..
wyników.find
(przynajmniej wersja GNU) wydaje się być zakodowana na stałe..
, nawet z-noleaf
.O(n^2)
i działafind
raz dla każdego członka zestawu plików dowiązanych na stałe.find ... -printf '%16i %p\n' | sort -n | uniq -w 16 --all-repeated=separate
działałby (16 nie jest wystarczająco szeroki, aby dziesiętna reprezentacja 2 ^ 63-1, więc gdy twój system plików XFS jest wystarczająco duży, aby mieć tak wysokie liczby i-węzłów, uważaj)Istnieje wiele odpowiedzi ze skryptami, aby znaleźć wszystkie dowiązania twarde w systemie plików. Większość z nich robi takie głupie rzeczy, jak uruchamianie funkcji wyszukiwania, aby skanować cały system plików w
-samefile
poszukiwaniu KAŻDEGO pliku z wieloma linkami. To jest szalone; wystarczy posortować według numeru i-węzła i wydrukować duplikaty.Za pomocą jednego przejścia przez system plików można znaleźć i zgrupować wszystkie zestawy plików dowiązanych na stałe
Jest to znacznie szybsze niż inne odpowiedzi na znalezienie wielu zestawów plików dowiązanych na stałe.
find /foo -samefile /bar
jest doskonały tylko dla jednego pliku.-xdev
: ograniczenie do jednego systemu plików. Nie jest to absolutnie potrzebne, ponieważ drukujemy również FS-id na uniq! -type d
odrzuć katalogi: wpisy.
i..
oznaczają, że zawsze są połączone.-links +1
: liczba linków ściśle> 1
-printf ...
wypisz FS-id, numer i-węzła i ścieżkę. (Z dopełnieniem do ustalonych szerokości kolumn, o których możemy powiedziećuniq
.)sort -n | uniq ...
sortuj numerycznie i unikaj pierwszych 42 kolumn, oddzielając grupy pustą liniąUżycie
! -type d -links +1
oznacza, że dane wejściowe sort są tak duże, jak końcowy wynik uniq, więc nie wykonujemy dużej ilości sortowania łańcuchów. Chyba że uruchomisz go w podkatalogu, który zawiera tylko jeden z zestawu dowiązań twardych. W każdym razie spowoduje to o wiele krótszy czas pracy procesora przez system plików niż w przypadku innych opublikowanych rozwiązań.próbka wyjściowa:
TODO ?: rozpakuj wyjście za pomocą
awk
lubcut
.uniq
ma bardzo ograniczone wsparcie wyboru pola, więc wpisuję wyniki wyszukiwania i używam stałej szerokości. 20 znaków jest wystarczająco szeroki, aby pomieścić maksymalny możliwy numer i-węzła lub urządzenia (2 ^ 64-1 = 18446744073709551615). XFS wybiera numery i-węzłów na podstawie miejsca, w którym są przydzielane na dysku, a nie od 0, więc duże systemy plików XFS mogą mieć> i-bitowe liczby i-węzłów, nawet jeśli nie mają miliardów plików. Inne systemy plików mogą mieć 20-cyfrowe numery i-węzłów, nawet jeśli nie są gigantyczne.DO ZROBIENIA: posortuj grupy duplikatów według ścieżki. Posortowanie ich według punktu montowania, a następnie liczba i-węzłów miesza rzeczy razem, jeśli masz kilka różnych podkatalogów, które mają wiele dowiązań twardych. (tzn. grupy dup-grup idą w parze, ale wynik miesza je).
Finał
sort -k 3
sortowałby linie osobno, a nie grupy linii jako pojedynczy rekord. Przetwarzanie wstępne z czymś, co przekształca parę znaków nowej linii w bajt NUL, i użycie GNUsort --zero-terminated -k 3
może załatwić sprawę.tr
działa tylko na pojedyncze znaki, a nie na 2-> 1 lub 1-> 2 wzorce.perl
zrobiłbym to (lub po prostu parsował i sortował w perl lub awk).sed
może również działać.źródło
%D
to identyfikator systemu plików (jest unikalny dla bieżącego rozruchu, gdy żadne systemy plików sąumount
ed), więc po jest jeszcze bardziej ogólna:find directories.. -xdev ! -type d -links +1 -printf '%20i %20D %p\n' | sort -n | uniq -w 42 --all-repeated=separate
. Działa to tak długo, jak długo dany katalog nie zawiera innego katalogu na poziomie systemu plików, a także sprawdza wszystko, co może być dowiązane na twardo (jak urządzenia lub softlink - tak, softlink może mieć liczbę linków większą niż 1). Należy pamiętać, żedev_t
iino_t
ma długość 64 bitów dzisiaj. Prawdopodobnie będzie tak długo, dopóki będziemy mieli 64-bitowe systemy.! -type d
zamiast-type f
. Mam nawet pewne dowiązania symboliczne w moim systemie plików z organizacji niektórych zbiorów plików. Zaktualizowałem moją odpowiedź o ulepszoną wersję (ale najpierw umieściłem fs-id, więc sortuj co najmniej grupy według systemu plików.)Jest to nieco komentarz do własnej odpowiedzi i skryptu Torocoro-Macho, ale oczywiście nie mieści się w polu komentarza.
Przepisz swój skrypt w prostszy sposób, aby znaleźć informacje, a tym samym znacznie mniej wywołań procesów.
Starałem się zachować jak najbardziej podobny do twojego, aby ułatwić porównanie.
Komentarze do tego skryptu i twojego
Zawsze należy unikać
$IFS
magii, jeśli glob jest wystarczający, ponieważ jest niepotrzebnie zawinięty, a nazwy plików mogą faktycznie zawierać znaki nowej linii (ale w praktyce głównie pierwszy powód).Powinieneś unikać ręcznego parsowania
ls
i takich danych wyjściowych, jak to możliwe, ponieważ prędzej czy później cię ugryzie. Na przykład: w pierwszymawk
wierszu nie powiodły się wszystkie nazwy plików zawierające spacje.printf
często oszczędza kłopotów, ponieważ jest tak odporny na%s
składnię. Daje także pełną kontrolę nad wyjściem i jest spójny we wszystkich systemach, w przeciwieństwie doecho
.stat
może zaoszczędzić ci dużo logiki w tym przypadku.GNU find
jest potężny.Twoje
head
itail
wywołania mogły być obsługiwane bezpośrednio zaawk
pomocą np.exit
Polecenia i / lub wyboruNR
zmiennej. Pozwoliłoby to zaoszczędzić wywołania procesów, które prawie zawsze znacznie poprawiają wydajność w ciężko pracujących skryptach.Twoje
egrep
równie dobrze mogą być sprawiedliwegrep
.źródło
find ... -xdev -type f -links +1 -printf '%16i %p\n' | sort -n | uniq -w 16 --all-repeated=separate
. Jest O DUŻO szybszy, ponieważ przemierza fs tylko raz. W przypadku wielu FS na raz, numery i-węzłów muszą być poprzedzone identyfikatorem FS. Może zfind -exec stat... -printf ...
Opierając się na
findhardlinks
skrypcie (przemianowanym nahard-links
), właśnie to zreformowałem i sprawiłem, że działa.Wynik:
źródło
Rozwiązanie GUI bardzo zbliża się do twojego pytania:
Nie można wyświetlić rzeczywistych plików dowiązań z „ls”, ponieważ, jak zauważyli poprzedni komentatorzy, „nazwy” plików są jedynie aliasami do tych samych danych. Jednak tak naprawdę istnieje narzędzie GUI, które naprawdę zbliża się do tego, czego chcesz, czyli wyświetlanie listy ścieżek nazw plików, które wskazują na te same dane (jako twarde linki) w systemie Linux, nazywa się FSLint. Opcja, którą chcesz znaleźć, znajduje się w „Zderzenia nazw” -> odznacz „pole wyboru $ ŚCIEŻKA” w Wyszukiwarce (XX) -> i wybierz „Aliasy” z rozwijanego menu po „dla ...” w kierunku górnej środkowej części.
FSLint jest bardzo słabo udokumentowany, ale stwierdziłem, że upewniłem się, że drzewo katalogu jest ograniczone pod „Ścieżką wyszukiwania” z zaznaczonym polem wyboru „Recurse?” oraz wyżej wspomniane opcje, lista danych połączonych na stałe ze ścieżkami i nazwami, które „wskazują” na te same dane, są tworzone po wyszukiwaniu programu.
źródło
Możesz skonfigurować
ls
podświetlanie linków twardych za pomocą „aliasu”, ale jak wspomniano wcześniej, nie ma sposobu, aby pokazać „źródło” linku twardego, dlatego dołączam.hardlink
do pomocy.Dodaj następujące gdzieś w swoim
.bashrc
źródło