Odpowiedzi:
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 locate
wdrożenia wszystkich jego opcji: -0
, -c
, -d
, -i
, -l
, -m
, -s
, i -S
. mlocate
realizuje 6 dodatkowych opcji nie w BSD locate
: -b
, -e
, -P
, -q
, --regex
i -w
. GNUlocate
realizuje te sześć plus trzy cztery : -A
, -D
, -E
i -p
. (Ignoruję pseudonimy i niewielkie różnice, takie jak -?
vs -h
vs. --help
).
BSD i Mac OS X dostarczają BSD locate
.
Większość Linuksów jest dostarczanych GNU locate
, ale mlocate
zamiast 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, locate
uruchomi się „ ” mlocate
.
Oracle jest dostarczany mlocate
w systemie Solaris od 11.2 , wydanego w grudniu 2014 r. Wcześniej locate
nie 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 findutils
z AIX Toolbox dla aplikacji Linux .
Wydaje się, że HP-UX również brakuje locate
w 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ć:
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 find
robi, ale BSD w locate
ogóle nie wykonuje wyrażeń regularnych. Jeśli jesteś podobny do mnie i musisz używać różnych typów maszyn, wolisz grep
filtrowanie niż rozwijanie zależności od -r
lub --regex
.
locate
potrzebuje silniejszego filtrowania niż find
to, 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 grep
filtrowania 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 -delete
i -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:
locate
potrafi nazywać pliki, które już nie istnieją.
GNU locate
i mlocate
mają -e
flagę, aby to sprawdzić istnienie pliku przed wydrukowaniem się nazwy każdego pliku odkryto w przeszłości, ale to pochłania część locate
przewagi prędkości, a nie jest dostępne w BSD locate
obok.
locate
nie uda się nazwać plików, które zostały utworzone od ostatniej aktualizacji bazy danych.
Nauczysz się być nieco nieufny wobec locate
wynikó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ż locate
zapewnia globalną usługę wszystkim użytkownikom w systemie, chce, aby updatedb
proces był uruchomiony, root
aby mógł zobaczyć cały system plików. Prowadzi to do wyboru problemów bezpieczeństwa:
Uruchom updatedb
jako root, ale uczyń jego plik wyjściowy czytelnym dla całego świata, aby locate
mó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 locate
jest skonfigurowany w ten sposób na Mac OS X i FreeBSD.
Zapisz bazę danych jako możliwą do odczytu tylko root
i zrób locate
setuid
root, aby mógł ją odczytać. Oznacza to, że locate
skutecznie 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 .
Utwórz specjalnego locate
użytkownika lub grupę, która będzie właścicielem pliku bazy danych, i zaznacz locate
plik binarny setuid/setgid
dla 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ć.
mlocate
jest skonfigurowany w ten sposób w systemie Red Hat Enterprise Linux .
Nadal masz problem, ponieważ jeśli możesz użyć debuggera locate
lub spowodować, że zrzuci on rdzeń , możesz uzyskać dostęp do uprzywilejowanych części bazy danych.
Nie widzę sposobu na stworzenie prawdziwie „bezpiecznego” locate
polecenia, 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.
find -- "$dir"
niezbyt solidny ( $dir
może być brany za predykat), nie ma możliwości przetestowania atrybutów dowiązania symbolicznego, problemów z wyścigiem ... Dla mnie find
i locate
rozwią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.
locate
grubsza przypominały find / -type f | gzip > locate.gz
, izgrep "$1" <locate.gz
locate
jest w findutils
pakiecie, a jego updatedb
program jest implementowany pod względem find(1)
. W tym sensie locate(1)
tak naprawdę wymaga find(1)
. :)
find
, locate
w 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.
locate
używa wstępnie zbudowanej bazy danych, która powinna być regularnie aktualizowana, podczas gdy find
iteruje po systemie plików w celu zlokalizowania plików.
Jest więc locate
znacznie 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 updatedb
polecenie).
Ponadto find
może oferować większą szczegółowość, ponieważ możesz filtrować pliki według każdego jego atrybutu, a jednocześnie locate
używa wzorca dopasowanego do nazw plików.
find
nie jest możliwe, aby nowicjusz lub okazjonalny użytkownik Uniksa z powodzeniem korzystał bez dokładnego przejrzenia strony podręcznika. Historycznie niektóre wersje find
nawet domyślnie tej -print
opcji nie zwiększały wrogości użytkownika.
locate
jest mniej elastyczny, ale o wiele bardziej intuicyjny w użyciu w zwykłym przypadku.
find . -name 'nametosearch'
lub -iname
dla 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.) :)
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.