Linuks, find, jak pozbyć się komunikatu “Permission denied”

Linuksowa komenda find jest dość potężna: potrafi nie tylko przeszukiwać foldery, ale również wykonywać dowolne polecenie systemu operacyjnego na znalezionych plikach. Może nie brzmi to zbyt ekscytująco, ale daje naprawdę ogromne możliwości.

find ma jednak jedną, niewielką wadę: jeżeli przeszukujemy dużo folderów, rosną szanse, że trafimy na folder, do którego nie mamy dostępu. W efekcie zobaczymy mnóstwo komunikatów w rodzaju "find: nazwa folderu: Permission denied"

Czasem takie "śmieci" mogą nam przeszkadzać. Jak się tego pozbyć?

Metod jest kilka. Najlepszą przedstawiam poniżej:

find . -name *czegoszukam* 2> >(grep -v "Permission denied" >&2)

Powyższa składnia jest dość egzotyczna, choć całkiem logiczna:

2> oznacza przekierowanie strumienia błędów do...

... >( jakaś komenda) - jeżeli po przekierowaniu wstawimy spację a potem polecenie zamknięte w >(...) to oznacza, że przekierowujemy dane do tej komendy. Tu mamy na końcu jeszcze >&2 oznaczające, że jakiekolwiek wyjście komendy grep ma trafić do strumienia numer 2 (czyli strumienia błędów).

Czyli, krok po kroku, nasza cała komenda oznacza:

  • znajdź wszystkie pliki zawierające w nazwie "czegoszukam"
  • jeżeli pojawią się jakiekolwiek błędy, wyślij je do komendy grep -v "Permission denied"
  • Jeżeli dany komunikat błędu zawiera tekst "Permission denied", zignoruj go (-v), w przeciwnym razie wyświetl w strumieniu błędów (>&2)

Trochę skomplikowane, ale to tak naprawdę najlepsza metoda: po pierwsze jest szybko, bo grep włączy się tylko w przypadku wystąpienia błędów (nie przepuszczamy przez grep-a wszystkich danych wygenerowanych przez find, tylko komunikaty błędów) - a po drugie zachowujemy kod wyjścia polecenia find (w razie gdybyśmy chcieli sprawdzić, czy w ogóle wystąpiły jakieś błędy).

Inne rozwiązania na ogół bazują na operatorze | który sprawia, że cała komenda zwróci kod wyjścia ("exit code") ostatniego polecenia w ciągu, czyli w tym przypadku grep. A używając przekierowania typu >(...) całość zwróci kod wyjścia polecenia find, czyli zgodnie z intuicją.

Nie wiem, czy kiedykolwiek przyjdzie mi użyć powyższego w praktyce, ale warto wiedzieć, że jest taka opcja.

4 komentarze

  1. Był kiedyś całkiem nieźle płatny konkurs na program w C zawierający najwyżej 100 znaków i rzeczywiście wykonujący jakiś złożony algorytm. Zwyciężał najbardziej “zakrzaczkowany” i nieczytelny kod. Język C świetnie się do tego nadaje. W Linuksie też można się tak bawić, choć tu muszą już występować “słowne” nazwy komend. Co ciekawe, nawet w starym, dobrym DOSie też można było pisać zagmatwane i kompletnie nieczytelne programy wsadowe.
    Tak sobie piszę konkludując, że miło jest posiadać moc, którą czasem można zadziwić świat lub ewentualnie samego siebie (bez względu na jej przydatność). 🙂

      1. Większość IDE ma funkcję zamiany wg wyrażenia regularnego. Wyszukujesz coś i podmieniasz np. tylko w wyszukaniu n-ty element. Szukasz więc konkretnego kawałka kodu, powiedzmy że konstruktora i zamieniasz piąty parametr oraz dodajesz za nim dwa nowe. Bez tego musiałbyś spędzić w dużym projekcie godziny ślęcząc i szukając na oko czy ten pasuje, czy nie pasuje do twojego zadania (wyszukanie referencji to za mało).
        A tak walczysz z wyrażeniem regularnym, spocisz się, a potem spijasz miód. To już zupełnie inna walka. 😉
        Pewnie nie w każdej robocie się to przydaje, ale sam wachlarz możliwości jest spory, a funkcja czasem niezauważana jako możliwość rozwiązania problemu.

Leave a Comment

Komentarze mile widziane.

Jeżeli chcesz do komentarza wstawić kod, użyj składni:
[code]
tutaj wstaw swój kod
[/code]