locate vs find czyli jak dobrze szukać plików

Tutaj można zadać pytanie, jeśli Linuksa widzi się pierwszy raz w życiu ;)
TJB
Sędziwy Jeż
Sędziwy Jeż
Posty: 36
Rejestracja: 05 paź 2010, 17:24
Płeć: Mężczyzna
Wersja Ubuntu: 10.04
Środowisko graficzne: GNOME
Architektura: x86

locate vs find czyli jak dobrze szukać plików

Post autor: TJB »

Kilkukrotnie miałem problemy z wyszukiwaniem plików, parę razy zdążyłem się nauczyć czym się oba polecenia różnią, ale nie dość głęboko, by dobrze i raz na zawsze zapamiętać. Dziś stwierdziłem, przy kolejnym zgryzie czemu wyniki obu się różnią jak się różnią, że zbyt często szukam jakichś fragmentów wiedzy o jednym lub drugim. Idąc za ciosem, postanowiłem skompilować tę wiedzę w jednym miejscu, a skoro już kompiluję, to dzielę się z innymi.

Odwołajmy się do źródła niezawodnego: Manuala.

1) man locate => locate - wyszukuje pliki w okresowo aktualizowanej bazie danych [...]
2) man find => find - szuka plików w hierarchii katalogowej [...]

Początkującym (choć nie tylko) często łatwiej przychodzi locate, które bez aktualizacji bazy będzie też znacząco szybsze, więcej rzeczy natomiast osiągniemy dzięki find (choć często we współpracy z czymś jeszcze). Natomiast warto jest wiedzieć o haczykach obu, by dobrze wybrać odpowiednio dla swojej potrzeby.

locate
* okresowa aktualizacja - stwórz plik test i spróbuj go zlokalizować. Bez aktualizacji bazy locate - nie uda Ci się. Inna strona tego samego medalu: usuń lub zmień nazwę pliku, a w bazie nadal będziesz miał stary wpis. Możesz albo poczekać na aktualizację (uruchamiane są zwykle nocą, administrator może to ustawić) albo wywołać (mając odpowiednie prawa)

Kod: Zaznacz cały

sudo updatedb
* szukanie w bazie danych ma swoje plusy i minusy. Baz może być wiele (można je wybrać z linii komend, parametrem dla polecenia locate), jeśli to Twój przypadek to Twoje locate niekoniecznie będzie jednym poleceniem (zwłaszcza jeśli jesteś nowicjuszem).
* PRUNEPATHS - locate nie szuka w miejscach określonych przez tą zmienną (PRUNEPATHS znajdziesz w /etc/updatedb.conf) - czasem to może zaskoczyć (np. jak się okaże, że katalog tymczasowy, lub gorzej: wszystkie podmontowywane urządzenia mające ścieżkę zaczynającą się od /mnt/... albo od /media/... są domyślnie wyłączone z locate).
* zewnętrzne nośniki - USB, płytki, inne takie - szukanie tu z locate może być problematyczne z racji dwu powyższych haczyków.


Zalety: szybkość, prostota obsługi, nie łazi po urządzeniach, indeksacja zwykle biegnie w tle, zatem nie powinna przeszkadzać, wreszcie nie przestrasza koniecznością poznania Basha (choć Bash nie jest taki straszny, jak go niektórzy malują).

Domyślnie szuka w całej bazie (czyli po wszystkich zindeksowanych plikach) i zakładając, że podałeś kawałek nazwy.

Kod: Zaznacz cały

a-desktop:~$ locate strona
/home/tjb/strona.css
/home/tjb/strona.html
/usr/share/pixmaps/faces/astronaut.jpg
Wielkość liter ma znaczenie:

Kod: Zaznacz cały

a-desktop:~$ locate -i rdz
/home/tjb/rdz_dziekanat
/home/tjb/Pulpit/Ubuntu_RDZ.txt
/home/tjb/Pulpit/rdz
/home/tjb/Pulpit/12M/RDZ
/home/tjb/Pulpit/zdjęcia/Zdjęcia/Moje obrazy/potwierdzenieWplaty.JPG
/home/tjb/bin/rdz.sh
a-desktop:~$ locate rdz
/home/tjb/rdz_dziekanat
/home/tjb/Pulpit/rdz
/home/tjb/Pulpit/zdjęcia/Zdjęcia/Moje obrazy/potwierdzenieWplaty.JPG
/home/tjb/bin/rdz.sh
find
Zacznę od przykładu:

Kod: Zaznacz cały

a-desktop:~$ find rdz
find: `rdz': Nie ma takiego pliku ani katalogu
a-desktop:~$ find rdz*
rdz_dziekanat
a-desktop:~$ find rdz\*
find: `rdz*': Nie ma takiego pliku ani katalogu
a-desktop:~$ find rdz*/*
find: `rdz*/*': Nie ma takiego pliku ani katalogu
a-desktop:~$ find rdz*\*
find: `rdz**': Nie ma takiego pliku ani katalogu
a-desktop:~$ find -name rdz*
./rdz_dziekanat
a-desktop:~$ find -name rdz\*
./Pulpit/rdz
./rdz_dziekanat
./bin/rdz.sh
* znaki specjalne powłoki są interpretowane(!), zatem nie używając \ łatwo wpaść w pułapkę, stosując np. * lub ?. Widać to wyraźnie przy szukaniu rdz*/* i rdz*\* - pierwsze szuka faktycznie rdz*/*, drugie szuka rdz**.
* wymaga precyzji: przy źle podanej ścieżce wyszukiwania albo złym podaniu poszukiwanego wzorca (np. bez name czy iname, albo z \* po tylko jednej stronie) banalnie prosto jest dostać kilkadziesiąt ekranów tekstu z wyników wyszukiwania... albo nie dostać wyników, o jakich wiemy, że są. Przykłady wyżej i niżej, z szukaniem 'rdz'.
* masa opcji, długa lektura by znaleźć to czego potrzebujesz, łatwo przeoczyć ustawienia domyślne lub o nich nie doczytać
* włazi toto wszędzie gdzie mu każesz. Nawet tam, gdzie nie powinien lub gdzie i tak nic nie znajdzie (w urządzenia np.). Rezultatem jest sporo haseł w stylu "Brak dostępu do urządzenia", co powoduje, że przy szukaniu o większym zakresie, komunikaty błędów trzeba po prostu wyciąć, by nie przegapić tego, czego szukamy. Wycinasz = przekierowujesz ich wydruk w pustkę, a nie na ekran. O, tak:

Kod: Zaznacz cały

find ścieżka opcje 2> /dev/null
Zalety: potęga narzędzia leży w jego łatwym dopasowaniu do innych narzędzi powłoki. Find nie tylko znajdzie pliki, ale umożliwi operacje na nich lub na ich treści. Ilość opcji polecenia to kilka ekranów. No i nie ma żadnych baz do aktualizowania, zrobiłeś zmianę, szukasz, widać jej efekt.

Domyślnie szuka w bieżącym katalogu, dokładnie tego, co mu kazałeś.

Kod: Zaznacz cały

a-desktop:~$ find strona
find: `strona': Nie ma takiego pliku ani katalogu
Wielkość znaków ma znaczenie, porównajcie powyżej wyniki szukania z -name rdz\* i tu:

Kod: Zaznacz cały

a-desktop:~$ find -iname rdz\*
./Pulpit/12M/RDZ
./Pulpit/rdz
./rdz_dziekanat
./bin/rdz.sh
Ważne jest też [b]gdzie[/b] damy ? albo * i czy zrobimy to bez \ czy z nim (choć to nie zawsze oba poniższe polecenia dają ten sam rezultat):
[code]
a-desktop:~$ find -iname *rdz\*
./przedświąteczneRDZy
./Pulpit/12M/RDZ
./Pulpit/rdz
./Pulpit/zdjęcia/Zdjęcia/Moje obrazy/potwierdzenieWplaty.JPG
./Pulpit/Ubuntu_RDZ.txt
./rdz_dziekanat
./bin/rdz.sh
a-desktop:~$ find -iname \*rdz\*
./przedświąteczneRDZy
./Pulpit/12M/RDZ
./Pulpit/rdz
./Pulpit/zdjęcia/Zdjęcia/Moje obrazy/potwierdzenieWplaty.JPG
./Pulpit/Ubuntu_RDZ.txt
./rdz_dziekanat
./bin/rdz.sh
Powodem jest Bash, a konkretnie tzw. ekspansja plików, (ang.: "file expansion"). Bash odwala za nas czarną robotę za każdym razem kiedy piszemy * czy ?. Np. ls abc?? oznacza w praktyce, że Bash poszuka w bieżącym katalogu wszystkiego, co zaczyna się na abc i ma potem jeszcze jakieś dwa znaki, inne niż / - czyli zawoła ls już z listą plików. Wołając:

Kod: Zaznacz cały

find -iname rdz*
mamy analogiczną sytuację: wpierw działa Bash, potem find. Bash robi podstawkę za * (czy ?, obojętne) i jak wołamy find, to już z parametrem -iname rdz... gdzie zamiast trzykropka wstawić należy listę plików z tych w bieżącym katalogu, które zaczynają się na rdz. Oprócz znaku / - i tu leży pies pogrzebany. Bo bez tego znaku / nie przejdziemy do podkatalogów. A jak zawołamy

Kod: Zaznacz cały

find -iname rdz\*
to podstawianiem za * czy ? zajmie się już find, a nie Bash.

Podsumowanie:
Na początek polecam locate. Szybkie, bardziej 'zgodne z oczekiwaniami' przeciętnego człowieka, mniej opcji do opanowania. W wielu przypadkach wystarcza, jak często podkreśla k2cl. Jak zacznie Ci brakować mocy, opcji, będzie uwierać opieranie się na bazie lub konieczność jej indeksacji - wybierz find.
Bodajże Ethanak podsumował dość zgrabnie różnicę: locate szuka gdzie coś BYŁO, a find, gdzie coś JEST. I bez odpalenia aktualizacji bazy - to jest bardzo trafne spostrzeżenie.


Źródła i dalsza lektura:
1) Manual

Kod: Zaznacz cały

man locate
man locatedb
man updatedb
man find
2) Posty na forum: search.php?keywords=find+locate
3) Angielskojęzyczne strony:
a) Ciekawsze zastosowania locate: http://linuxservertutorials.blogspot.co ... ocate.html
b) Parę sposobów z find: http://eriwen.com/productivity/find-is- ... iful-tool/
c) Dobra strona dla find: http://www.linux.ie/newusers/beginners- ... e/find.php
4) Warta osobnego wyróżnienia strona anglojęzyczna, gruntownie omawiająca szukanie plików w Ubuntu: graficznie (4 narzędzia) i z linii poleceń (6, wliczając find i locate).
ODPOWIEDZ

Wróć do „Przedszkole Linuksa”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 4 gości