locate vs find: wykorzystanie, zalety i wady

Odpowiedzi:

166

locate(1)ma tylko jedną dużą przewagę nad find(1): szybkość.

find(1)ma jednak wiele zalet w stosunku do locate(1):

  • find(1)jest pierwotny, wraca do pierwszej wersji AT&T Unix . Znajdziesz go nawet w odciętych osadzonych Linuxach poprzez Busybox . To wszystko jest uniwersalne.

    locate(1)jest znacznie młodszy niż find(1). Najstarszy przodek locate(1) pojawił się dopiero w 1983 r. I nie był szeroko dostępny jako „ locate” do 1994 r., Kiedy to został adoptowany do GNU findutils i 4.4BSD .

  • locate(1)jest również niestandardowy , dlatego nie jest instalowany domyślnie wszędzie. Niektóre systemy operacyjne typu POSIX nawet nie oferują tego jako opcji, a tam, gdzie jest dostępna, implementacja może nie mieć pożądanych funkcji, ponieważ nie ma niezależnego standardu określającego minimalny zestaw funkcji, który musi być dostępny.

    Jest to de facto standard, będąc BSDlocate(1) , ale to tylko dlatego, że pozostałe dwa główne smaki locatewdrożenia wszystkich jego opcji: -0, -c, -d, -i, -l, -m, -s, i -S. mlocaterealizuje 6 dodatkowych opcji nie w BSD locate: -b, -e, -P, -q, --regexi -w. GNUlocate realizuje te sześć plus trzy cztery : -A, -D, -Ei -p. (Ignoruję pseudonimy i niewielkie różnice, takie jak -?vs -hvs. --help).

    BSD i Mac OS X dostarczają BSD locate.

    Większość Linuksów jest dostarczanych GNU locate, ale mlocatezamiast nich Linux i Red Hat . Debian nie instaluje się w podstawowej instalacji, ale oferuje obie wersje w domyślnych repozytoriach pakietów; jeśli oba zostaną zainstalowane jednocześnie, locateuruchomi się „ ” mlocate.

    Oracle jest dostarczany mlocatew systemie Solaris od 11.2 , wydanego w grudniu 2014 r. Wcześniej locatenie był domyślnie instalowany w systemie Solaris. (Prawdopodobnie zrobiono to w celu zmniejszenia niezgodności poleceń Solaris z Oracle Linux , który jest oparty na Red Hat Enterprise Linux , który również używa mlocate.)

    IBM AIX nadal nie dostarcza żadnej wersji locate, przynajmniej od AIX 7.2 , chyba że zainstalujesz GNU findutilsz AIX Toolbox dla aplikacji Linux .

    Wydaje się, że HP-UX również brakuje locatew systemie podstawowym.

    Starsze „prawdziwe” uniksy generalnie nie zawierały implementacji locate.

  • find(1)ma potężną składnię wyrażeń, z wieloma funkcjami, operatorami boolowskimi itp.

  • find(1)może wybierać pliki nie tylko według nazwy. Można wybrać:

    • wiek
    • rozmiar
    • właściciel
    • Typ pliku
    • znak czasu
    • uprawnienia
    • głębokość w poddrzewie ...
  • Podczas wyszukiwania plików według nazwy można wyszukiwać za pomocą składni globowania plików we wszystkich wersjach find(1)lub w wersjach GNU lub BSD, używając wyrażeń regularnych .

    Obecne wersje locate(1)akceptujących wzorce globów, jak to findrobi, ale BSD w locateogóle nie wykonuje wyrażeń regularnych. Jeśli jesteś podobny do mnie i musisz używać różnych typów maszyn, wolisz grepfiltrowanie niż rozwijanie zależności od -rlub --regex.

    locatepotrzebuje silniejszego filtrowania niż findto, ponieważ ...

  • find(1)niekoniecznie przeszukuje cały system plików. Zazwyczaj wskazuje się na podkatalog, nadrzędny zawierający wszystkie pliki, na których ma on działać. Typowe zachowanie dla locate(1)implementacji polega na wyrzuceniu wszystkich plików pasujących do wzorca, pozostawiając go do grepfiltrowania i w ten sposób, aby zmniejszyć jego erupcję do rozmiaru.

    (Zła wskazówka: locate /prawdopodobnie dostaniesz listę wszystkich plików w systemie!)

    Istnieją warianty locate(1)podobnych, slocate(1)które ograniczają dane wyjściowe na podstawie uprawnień użytkownika, ale nie jest to domyślna wersja locateżadnego większego systemu operacyjnego.

  • find(1)może robić różne rzeczy na plikach, które znajdzie, oprócz ich wyszukiwania. Najpotężniejszym i najczęściej obsługiwanym takim operatorem jest -exec, ale są też inni. W ostatnich implementacjach GNU i BSD znajdują się na przykład operatory -deletei -execdir.

  • find(1) działa w czasie rzeczywistym, więc jego dane wyjściowe są zawsze aktualne.

    Ponieważ locate(1)w przeszłości baza danych jest aktualizowana kilka godzin lub dni, jej dane wyjściowe mogą być nieaktualne. (Jest to problem przestarzałej pamięci podręcznej .) Moneta ma dwie strony:

    1. locate potrafi nazywać pliki, które już nie istnieją.

      GNU locatei mlocatemają -eflagę, aby to sprawdzić istnienie pliku przed wydrukowaniem się nazwy każdego pliku odkryto w przeszłości, ale to pochłania część locateprzewagi prędkości, a nie jest dostępne w BSD locateobok.

    2. locate nie uda się nazwać plików, które zostały utworzone od ostatniej aktualizacji bazy danych.

    Nauczysz się być nieco nieufny wobec locatewyników, wiedząc, że to może być źle.

    Istnieją sposoby rozwiązania tego problemu, ale nie jestem świadomy żadnej implementacji w powszechnym użyciu. Na przykład istnieje rlocate, ale wydaje się, że nie działa przeciwko żadnemu współczesnemu jądru Linuksa.

  • find(1) nigdy nie ma żadnych przywilejów niż użytkownik go uruchamiający.

    Ponieważ locatezapewnia globalną usługę wszystkim użytkownikom w systemie, chce, aby updatedbproces był uruchomiony, rootaby mógł zobaczyć cały system plików. Prowadzi to do wyboru problemów bezpieczeństwa:

    1. Uruchom updatedbjako root, ale uczyń jego plik wyjściowy czytelnym dla całego świata, aby locatemógł działać bez specjalnych uprawnień. To skutecznie udostępnia nazwy wszystkich plików w systemie wszystkim użytkownikom. Może to być wystarczające naruszenie bezpieczeństwa, aby spowodować prawdziwy problem.

      BSD locatejest skonfigurowany w ten sposób na Mac OS X i FreeBSD.

    2. Zapisz bazę danych jako możliwą do odczytu tylko rooti zrób locate setuidroot, aby mógł ją odczytać. Oznacza to, że locateskutecznie musi ponownie wdrożyć system uprawnień systemu operacyjnego, aby nie wyświetlał plików, których normalnie nie widać. Zwiększa także powierzchnię ataku twojego systemu, szczególnie ryzykując atak eskalacji korzenia .

    3. Utwórz specjalnego locateużytkownika lub grupę, która będzie właścicielem pliku bazy danych, i zaznacz locateplik binarny setuid/setgiddla tego użytkownika / grupy, aby mógł czytać bazę danych. Nie zapobiega to samemu atakowi eskalacji uprawnień, ale znacznie zmniejsza szkody, jakie możesz wyrządzić.

      mlocatejest skonfigurowany w ten sposób w systemie Red Hat Enterprise Linux .

      Nadal masz problem, ponieważ jeśli możesz użyć debuggera locatelub spowodować, że zrzuci on rdzeń , możesz uzyskać dostęp do uprzywilejowanych części bazy danych.

    Nie widzę sposobu na stworzenie prawdziwie „bezpiecznego” locatepolecenia, bez uruchamiania go osobno dla każdego użytkownika w systemie, co neguje wiele jego zalet find(1).

Podsumowując, oba są bardzo przydatne. locate(1)jest lepszy, gdy próbujesz znaleźć konkretny plik według nazwy, o której wiesz, że istnieje, ale po prostu nie pamiętasz, gdzie dokładnie jest. find(1)jest lepszy, gdy masz skoncentrowany obszar do zbadania lub gdy potrzebujesz jednej z jego wielu zalet.

Warren Young
źródło
Przepraszam, przeoczyłem akapit „slocate”. rlocate rozwiązuje problem przestarzałej pamięci podręcznej . Być może zechcesz wspomnieć o niektórych dziwactwach znalezienia, takich jak find -- "$dir" niezbyt solidny ( $dirmoże być brany za predykat), nie ma możliwości przetestowania atrybutów dowiązania symbolicznego, problemów z wyścigiem ... Dla mnie findi locaterozwiązania dwóch różnych problemów. Istnieje wiele miejsc, w których użycie find nie jest realistyczne (np. Katalogi zawierające miliony plików). locate to system indeksowania ograniczony do nazw plików.
Stéphane Chazelas
2
Pierwsze wdrożenia z locategrubsza przypominały find / -type f | gzip > locate.gz, izgrep "$1" <locate.gz
F. Hauri
@ F.Hauri: Ciekawe ciekawostki. Oto więcej: GNU locatejest w findutilspakiecie, a jego updatedbprogram jest implementowany pod względem find(1). W tym sensie locate(1)tak naprawdę wymaga find(1) . :)
Warren Young,
1
@WarrenYoung dlaczego istnieje stałe odniesienie do foo (1) zamiast po prostu foo? czy są różne wersje foo?
orzechowy o natty
4
@nuttyaboutnatty: Jest to starożytny konwencja w Unix, instrukcje obsługi, czyli punkt instrukcji 1. O ile prawdą jest, że nie ma find, locatew innych sekcjach, itd., więc nie musi być tam disambiguate taką samą nazwę używaną w różnych sekcjach podręcznik (np. unlink(1)vs unlink(2)), ci z nas przyzwyczajeni do konwencji widzą to jako odniesienie do strony podręcznika man.
Warren Young,
35

locateużywa wstępnie zbudowanej bazy danych, która powinna być regularnie aktualizowana, podczas gdy finditeruje po systemie plików w celu zlokalizowania plików.

Jest więc locateznacznie szybszy niż find, ale może być niedokładny, jeśli baza danych - może być postrzegana jako pamięć podręczna - nie zostanie zaktualizowana (patrz updatedbpolecenie).

Ponadto findmoże oferować większą szczegółowość, ponieważ możesz filtrować pliki według każdego jego atrybutu, a jednocześnie locateużywa wzorca dopasowanego do nazw plików.

użytkownik435943
źródło
7

findnie jest możliwe, aby nowicjusz lub okazjonalny użytkownik Uniksa z powodzeniem korzystał bez dokładnego przejrzenia strony podręcznika. Historycznie niektóre wersje findnawet domyślnie tej -printopcji nie zwiększały wrogości użytkownika.

locate jest mniej elastyczny, ale o wiele bardziej intuicyjny w użyciu w zwykłym przypadku.

Russell Borogove
źródło
1
Z drugiej strony locate musi utrzymywać bazę danych i uruchamiać ją okresowo, więc wyłączyłem ją na wszystkich serwerach Linux, które znajdują się w naszej prywatnej sieci.
Rui F Ribeiro,
2
Co jest w tym trudnego? find . -name 'nametosearch'lub -inamedla bez rozróżniania wielkości liter. Zamień .na ścieżkę do katalogu, aby wyszukać inny niż bieżący katalog. Tam jest to 90% wymagań początkujących użytkowników, nawet bez wchodzenia w globbing plików. (Zasadniczo korzystam, find . -iname '*partialfilename*'a jeśli szukam /, używam, find / -maxdepth 5 -iname '*partialname*'co skraca czas wyszukiwania, znajdując wszystko, co mnie interesuje w 90% przypadków. Tam 75% wymagań użytkowników pośrednich.) :)
Wildcard
2

Niewielką wadą lokalizacji jest to, że może nie indeksować obszaru systemu plików, który Cię interesuje. W systemach komputerowych Debiana, na przykład Linux Mint 17.2, plik /etc/updatedb.conf jest skonfigurowany tak, aby wykluczyć niektóre obszary z rozpatrzenia , w tym / tmp, / var / spool i /home/.ecryptfs.

Ignorowanie /home/.ecryptfs zapobiega ujawnieniu nazw plików w zaszyfrowanych katalogach nieautoryzowanym użytkownikom. Jeśli jednak twój katalog domowy jest zaszyfrowany za pomocą ecryptfs, oznacza to również, że twój katalog domowy nie jest indeksowany i dlatego lokalizowanie nigdy nie znajdzie niczego w twoim katalogu domowym. To może uczynić go w dużej mierze bezużytecznym dla ciebie (robi to dla mnie). Oprócz nie znajdowania wyników, proces updatedb okresowo ładuje dysk bez korzyści i równie dobrze może zostać wyłączony, jeśli jesteś głównym lub jedynym użytkownikiem systemu.

Jim
źródło