Jak sprawić, by find podążał za większością, ale nie wszystkimi, symbolicznymi linkami?

10

Mój system operacyjny i katalog domowy znajdują się na dysku SSD. Przechowuję niektóre duże pliki na dysku twardym, a dowiązanie symboliczne z mojego katalogu domowego na dysk twardy (np. ~ / Video / Films jest dowiązaniem symbolicznym do / mnt / hdd / Films). Mam również wiele prefiksów Wine, z których każdy ma dosdevices / z: symlinked to /.

Tak więc, jeśli użyłem funkcji znajdź bez opcji -L, pominie to wszystko, co jest na dysku twardym. Ale jeśli użyję find z -L, to kończy się w pętli z powodu dowiązania symbolicznego Wine do /.

Czy istnieje jakiś rozsądny sposób rozwiązania tego problemu, aby znaleźć wyszukiwania tam, gdzie chcę? Intuicyjnie chcę coś w stylu „podążaj za dowiązaniami symbolicznymi, chyba że znajdują się w katalogu o nazwie dosdevices”. „Śledź dowiązania symboliczne, które prowadzą do czegoś na dysku twardym” również by działały.

Mark Raymond
źródło

Odpowiedzi:

11

-prunePodstawowym mówi findnie recurse ramach katalogu.

find -L -path ~/.wine/dosdevices -prune -o -type f -name 'My Favorite Movie.*' -print

Jeśli chcesz użyć -lnamew swoim stanie, nie możesz użyć tej -Lopcji, ponieważ -Lpowoduje , że większość predykatów działa na cel łącza, w tym -lname. W takim przypadku zalecam użycie katalogu głównego i katalogu głównego dysku twardego jako katalogu głównego wyszukiwania.

find ~ /mnt/hdd -xtype f -name 'My Favorite Movie.*'

Możesz uruchomić, find ~ -type l …aby zebrać listę dowiązań symbolicznych i użyć ich jako dodatkowych korzeni.

( IFS=$'\n'; set -f;
  find ~ $(find ~ -type l -lname '/mnt/hdd/*') \
       -xtype f -name 'My Favorite Movie.*' )

Jeśli naprawdę chcesz się powtarzać pod symbolicznymi linkami, możesz wykluczyć określone linki symboliczne według celu zamiast nazwy. Można jednak wykluczyć tylko skończoną listę, a nie wzorzec lub poddrzewo w ten sposób.

find -L \( -samefile /exclude/this -o -samefile ~/and/that \) -prune -o \
     -type f -name 'My Favorite Movie.*' -print

Możesz użyć innych kryteriów, takich jak ! -writable(pliki, do których nie masz uprawnień do zapisu), ale nie sądzę, że GNU find ma sposób na rekurencję pod dowiązaniami symbolicznymi tylko wtedy, gdy ich tekst docelowy pasuje do określonego wyrażenia.

Możesz zbudować findpolecenie, które robi prawie to, co chcesz, z wyjątkiem tego, że nie wyklucza wystarczającej liczby dowiązań symbolicznych, uruchom find2perl, aby przekonwertować zapytanie na skrypt Perla i nieco ulepszyć skrypt Perla. Istnieje jednak wiele przełączników GNU find, których find2perl nie rozpoznaje.

Gilles „SO- przestań być zły”
źródło
Dzięki! -prunejest właśnie tym, czego szukałem. Znalazłem find ~ \( -lname ~ -o -lname ~/\* -o -lname / \) -xtype dlistę wszystkich dowiązań symbolicznych, których nie chcę śledzić; Próbuję teraz znaleźć sposób na użycie tego zapytania do przycinania.
Mark Raymond
@ MarkRaymond Ogólna zasada jest find ~ <negative criteria> -prune -o <positive criteria> -printtaka, żefind ~ \( -lname ~ -o -lname ~/\* -o -lname / \) -xtype d -prune -o <whatever it is you want> -print
Gilles „SO- przestań być zły”
@Giles - działa dobrze bez -L, ale kiedy dodam -L, wyrażenia -lname już nie działają (tak jak strona podręcznika mówi, że nie będą). Zasadniczo potrzebuję więc pewnych warunków, aby podążać za dowiązaniami symbolicznymi, a innych nie!
Mark Raymond
Nie mogę wymyślić sposobu na zrobienie dokładnie tego, co chcesz za pomocą find. Zobacz moją edycję w celu uzyskania przybliżeń.
Gilles „SO- przestań być zły”
1

Aby przeszukać WSZYSTKIE linki, działało to dla mnie:

find -L . -name \*.txt
Jim
źródło
0

Ile masz dowiązań symbolicznych do dysków twardych? Jeśli nie jest to zbyt wiele, jednym rozwiązaniem jest nieużywanie „-L”, przy jednoczesnym wyraźnym określaniu dowiązań symbolicznych, które chcesz śledzić w wierszu polecenia find. Coś jak:

find .  ~/Videos/Films -name '*file I want*' ...

Przeszuka bieżący katalog („.”), A także dowiązanie symboliczne „~ / Videos / Films”, ale nie zejdzie do innych dowiązań symbolicznych.

John1024
źródło
0

Innym rozwiązaniem, które rozwiązuje problem (przynajmniej w moim przypadku), jest użycie montowań powiązań zamiast dowiązań symbolicznych do katalogów na dysku twardym. Odbywa się to poprzez dodanie wpisów w /etc/fstabnastępujący sposób:

/mnt/hdd/Films /home/mark/Videos/Films none bind 0 0

Mark Raymond
źródło