Czy twarde linki liczą się jako zwykłe pliki?

21

Zastanawiałem się, czy istnieje sposób, aby to zarejestrować, ale ponieważ większość współczesnych wyszukiwarek nie działa dobrze z frazami o długości około 5 słów, potrzebuję pomocy w tym.

Zastanawiałem się nad tym, ponieważ tworzę skrypt bash, który musi rejestrować pliki jako określone typy i odpowiednio podejmować decyzje. Z technicznego punktu widzenia nie jest to ważne dla mojego projektu, ale byłem ciekawy.

Ponadto, jeśli są one uważane za zwykłe pliki, to czy istnieje sposób, aby sprawdzić, czy te pliki są na stałe połączone bez konieczności analizowania ls -i? I czy istnieje sposób, aby sprawdzić, czy jakiś dowolny plik, X, jest na stałe połączony z jakimkolwiek innym plikiem Y, bez użycia find -ipolecenia?

Pan Minty Fresh
źródło
5
W przypadku twardych linków „X” nie jest tak naprawdę powiązany z „Y”. „X” i „Y” są tym samym plikiem.
jordanm,
6
Wszystkie „zwykłe pliki” w katalogu są dowiązaniami stałymi. Niektóre takie pliki mają więcej niż jeden.
Andrew Henle,
@AndrewHenle Wow, dobry punkt. Właśnie tego szukałem, więc dziękuję.
Pan Minty Fresh
2
@ Mr.MintyFresh W szczególności nie ma rozróżnienia między „oryginalnym” a „linkiem”, tak jak w przypadku linków symbolicznych.
Random832

Odpowiedzi:

38

W systemach uniksowych struktura danych reprezentująca obiekty systemu plików (innymi słowy dane o pliku) jest przechowywana w tak zwanym „i-węzle”.

Nazwa pliku jest tylko linkiem do tego i-węzła i jest nazywana „twardym łączem”. Nie ma różnicy między pierwszym imieniem pliku a dowolnym kolejnym linkiem. Odpowiedź brzmi: „tak”: twardy link to zwykły plik, a rzeczywiście zwykły plik to twardy link.

lsKomenda pokaże ile trudno linki są do pliku.

Na przykład:

seumasmac@comp:~$ echo Hello > /tmp/hello.txt
seumasmac@comp:~$ ls -l /tmp/hello.txt 
-rw-rw-r-- 1 seumasmac seumasmac 6 Oct  4 13:05 /tmp/hello.txt

Tutaj stworzyliśmy plik o nazwie /tmp/hello.txt. Dane 1wyjściowe z ls -lwskazują, że istnieje 1 twardy link do tego pliku. Ten twardy link jest samą nazwą pliku /tmp/hello.txt.

Jeśli teraz utworzymy kolejny twardy link do tego pliku:

seumasmac@comp:~$ ln /tmp/hello.txt /tmp/helloagain.txt
seumasmac@comp:~$ ls -l /tmp/hello*
-rw-rw-r-- 2 seumasmac seumasmac 6 Oct  4 13:05 /tmp/helloagain.txt
-rw-rw-r-- 2 seumasmac seumasmac 6 Oct  4 13:05 /tmp/hello.txt

widać teraz, że obie nazwy plików wskazują, że istnieją 2 twarde linki do pliku. Żadna z tych nie jest „prawidłową” nazwą pliku, oba są jednakowo prawidłowe. Widzimy, że oba wskazują na tę samą i-węzeł (w tym przypadku 5374043):

seumasmac@comp:~$ ls -i /tmp/hello*
5374043 /tmp/helloagain.txt  5374043 /tmp/hello.txt

Istnieje powszechne nieporozumienie, że jest inaczej w przypadku katalogów. Słyszałem, jak ludzie mówią, że liczba odsyłaczy lsdo katalogu jest liczbą podkatalogów, w tym .i ..która jest niepoprawna . A przynajmniej, podając prawidłowy numer, jest odpowiedni z niewłaściwych powodów!

Jeśli tworzymy katalog i wykonujemy ls -ld:

seumasmac@comp:~$ mkdir /tmp/testdir
seumasmac@comp:~$ ls -ld /tmp/testdir
drwxrwxr-x 2 seumasmac seumasmac 4096 Oct  4 13:20 /tmp/testdir

To pokazuje, że istnieją 2 twarde linki do tego katalogu. To są:

/tmp/testdir
/tmp/testdir/.

Pamiętaj, że /tmp/testdir/..to nie jest link do tego katalogu, to link do /tmp. A to mówi ci, dlaczego działa „liczba podkatalogów”. Kiedy tworzymy nowy podkatalog:

seumasmac@comp:~$ mkdir /tmp/testdir/dir2
seumasmac@comp:~$ ls -ld /tmp/testdir
drwxrwxr-x 3 seumasmac seumasmac 4096 Oct  4 13:24 /tmp/testdir

teraz możesz zobaczyć 3 twarde linki do /tmp/testdirkatalogu. To są:

/tmp/testdir
/tmp/testdir/.
/tmp/testdir/dir2/..

Tak więc każdy nowy podkatalog zwiększy liczbę linków o jeden, ze względu na ..wpis, który zawiera.

seumasmac
źródło
Rozumiem, jak działają metadane, i-węzły i twarde linkowanie. Potrzebowałem tylko wyjaśnienia, czy plik z twardym dowiązaniem był liczony jako zwykły plik. To pokazuje mi tylko, że odpowiedź brzmi „tak” z powodu kolumny poświęconej temu, co domyślnie wskazuje, że jest to natywne dla wszystkich plików. Tak mi przykro, ale będę musiał to zagłosować :(
Mr. Minty Fresh
W porządku, jestem pewien, że będą to przydatne informacje dla kogoś innego.
seumasmac,
Ciekawa edycja z systemem hardlink dotglob, nigdy nie wiedziałam, że to robi.
Pan Minty Fresh
Wyjaśniłem twardy link == akapit zwykłych plików.
seumasmac,
1
Szczególnie jak zdanie: „Żadna z tych nazw nie jest„ poprawna ”, oba są jednakowo ważne”. Jest to kluczowy składnik zrozumienia twardych linków. Bardzo ładnie napisane.
Wildcard,
4

Czy twarde linki liczą się jako zwykłe pliki?

Twarde linki liczą się jako wszystko, z czym są połączone. Możesz połączyć się z dowolnym plikiem w tym samym systemie plików.

mkdir test
cd !$

>file
ln -s file sym
mknod pipe p

ln file file2
ln -P sym sym2
ln pipe pipe2

ls -al

# sockets, too:
cat >tsock.c <<\EOD
#include <sys/socket.h>
#include <sys/un.h>
int main(int n, char **a)
{
        struct sockaddr_un test = { AF_UNIX, "socket" };
        int testfd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
        bind(testfd,(struct sockaddr *)&test,sizeof test);
}
EOD
make tsock
./tsock

ln socket socket2

ls -al

# even devices if you want:
sudo mknod mytty c 5 0
ln mytty mytty2
sudo chmod 666 mytty

ls -al
# notice permissions are on an object not on the links to it:
echo Hi, Kilroy! >mytty2  

Każde dowiązanie twarde do czegokolwiek jest równoważne, leżący pod nim obiekt pozostaje tak długo, jak długo jest do niego link (edytuj: nie-symboliczny) (nawet otwarty deskryptor pliku, za co mam kłopotliwe powody).

System wymusi reguły dotyczące linków do katalogu, otrzymasz jeden nazwany link do katalogu, a system automatycznie doda .link osadzony i wszystkie ..linki do podkatalogów (zauważ, że .w powyższym ls ma dwa linki), ale to jest wyraźna kontrola, w przypadku niektórych zmodyfikowanych uprzywilejowani użytkownicy systemów, którzy obiecują, że nie będą tworzyć pętli, mogą sami dodawać nowe linki. System plików nie dba o to, może dobrze reprezentować dowolne wykresy katalogów, ale nikt nie chce się nimi zajmować.

Istnieją (wiele nie-uniksowych) systemów plików, które nie działają w ten sposób, w tym niektóre, które nazywają to, co oferują jako zastępcze „twarde łącza”. OS X podniósł odpowiednik na HFS + (który nie ma ich natywnie), jeśli dobrze pamiętam, nie wiem, jak wiernie zachowuje tutaj semantykę.

jthill
źródło
co ./tsockwłaściwie właściwie robi?
mikeserv
@mikeserv Jest to program make-a-socket powyżej, po prostu upuszcza link do gniazda o nazwie „socket” w bieżącym katalogu.
jthill
ok, ale może powinienem był wyjaśnić, jak mało wiem o gniazdach. myślę, że rozumiem linki wystarczająco dobrze, więc nadaje temu samemu gniazdu nową nazwę, prawda? to nie ma żadnego specjalnego znaczenia dla gniazd lub czegokolwiek, tak? przepraszam za moją ignorancję.
mikeserv
1
@mikeserv Gniazdo jest wyłącznie jednostką wykonawczą. socket()tworzy rzeczywiste gniazdo, bind()nadaje mu konkretną nazwę, connect()łączy utworzone gniazdo z jakimś nazwanym gniazdem. Różne rodzaje gniazd używają różnych nazw, np. Gniazda internetowe używają adresów internetowych, ale wszystkie mają wspólne API (w tym read()i write(), bardzo mi przykro, że nie możesz mieć open()gniazda systemu plików i masz system operacyjny lub libc socket()i connect()dla ciebie) . man 7 socketma więcej, wszystkie protokoły sieciowe tworzą niezrozumiałą stronę.
jthill
1
@mikeserv Zobacz, potrafię przeliterować pty i pts, a prawdopodobnie nawet ptmx w dobry dzień, ale to wszystko. :-) przynajmniej węzeł 5,0 działa wszędzie, co mogę znaleźć, jest to typ kontrolującego urządzenia. Mam to tylko z ls -l / dev / tty, chyba mam tam szczęście.
jthill