Jakie są dokładne powody, dla których `grep` w / proc i raw disk jest złym pomysłem?

8

Pobiegłem grep -r "searchphrase" / dzisiaj i to nie zadziałało. Zrobiłem trochę badań i znalazłem find / -xdev -type f -print0 | xargs -0 grep -H "searchphrase" być właściwym podejściem.

Zbieram /proc i dyski jak /dev/sda1 są winowajcami nieudanego grepa.

Uwielbiałbym głębokie zaplecze techniczne dotyczące „dlaczego”. Myślę, że niektóre linki wewnątrz /proc stwórz nieskończone pętle po przejściu, a czytam, że jest więcej powodów, ale nic konkretnego.

Co się dzieje, gdy surowy dysk jest grepowany? Czy dane binarne (dostępne na /dev/sda1, o ile wiem?) nie należy interpretować, ponieważ tylko a mount dzięki typowi systemu plików dane z dysku są zrozumiałe? Czy nadal byłoby możliwe grep dla ciągu binarnego?

krork
źródło

Odpowiedzi:

10

Tak, możesz grep /dev/sda1 i /proc ale prawdopodobnie nie chcesz. Bardziej szczegółowo:

  1. Tak, możesz uruchomić grep zawartość binarną /dev/sda1. Jednak w przypadku nowoczesnych dużych dysków twardych zajmie to bardzo dużo czasu, a wynik prawdopodobnie nie będzie przydatny.

  2. Tak, możesz grep zawartość /proc ale pamiętaj, że pamięć twojego komputera jest tam odwzorowana jako pliki. Na nowoczesnym komputerze z gigabajtami pamięci RAM zajmie to dużo czasu grep, a wynik prawdopodobnie nie będzie przydatny.

Wyjątkowo, jeśli szukasz danych na dysku twardym z uszkodzonym systemem plików, możesz uruchomić grep something /dev/sda1 jako część próby odzyskania danych pliku.

Inne problematyczne pliki w /dev

Dyski twarde i partycje dysku twardego pod /dev może być, jeśli ma się dość cierpliwości, grepped. Inne pliki (wskazówka: użytkownik2313067 ) może jednak powodować problemy:

  1. /dev/zero jest plikiem o nieskończonej długości. Na szczęście, grep (przynajmniej wersja GNU) jest wystarczająco inteligentna, aby ją pominąć:

    $ grep something /dev/zero
    grep: input is too large to count
    
  2. /dev/random i /dev/urandom są także nieskończone. Komenda grep something /dev/random będzie działać wiecznie, chyba że grep jest sygnalizowane zatrzymaniem.

    Może to być przydatne do grep /dev/urandom podczas generowania haseł. Aby uzyskać na przykład pięć losowych znaków alfanumerycznych:

    $ grep --text -o '[[:alnum:]]' /dev/urandom | head -c 10
    G
    4
    n
    X
    2
    

    To nie jest nieskończone, ponieważ po otrzymaniu wystarczającej liczby znaków head zamyka potok powodujący zakończenie grep.

Nieskończone pętle

„... linki ... tworzą nieskończone pętle po przejściu ...”

Grep (przynajmniej wersja GNU) jest wystarczająco inteligentny, aby tego nie robić. Rozważmy dwa przypadki:

  1. Z -r opcja, grep nie podążaj za dowiązaniami symbolicznymi, chyba że są wyraźnie określone w linii poleceń. Stąd nieskończone pętle nie są możliwe.

  2. Z -R opcja, grep robi podążaj za dowiązaniami symbolicznymi, ale sprawdza je i odmawia złapania w pętlę. Ilustrować:

    $ mkdir a
    $ ln -s ../ a/b
    $ grep -R something .
    grep: warning: ./a/b: recursive directory loop
    

Wykluczenie problematycznych katalogów grep -r

Tak na marginesie, grep zapewnia ograniczoną możliwość zatrzymania grep w wyszukiwaniu określonych plików lub katalogów. Na przykład możesz wykluczyć wszystkie nazwane katalogi proc, sys, i dev z rekurencyjnego wyszukiwania grep za pomocą:

grep --exclude-dir proc --exclude-dir sys --exclude-dir dev -r something /

Alternatywnie możemy wykluczyć proc, sys, i dev używając rozszerzonych globów basha:

shopt -s extglob
grep -r something /!(proc|sys|dev)
John1024
źródło
Dzięki! To świetna odpowiedź. Chyba, że ​​dziś z ciemności wyłoni się inny bohater, przyjmuję to jutro! Zastanawiam się nad jeszcze jedną rzeczą i mam nadzieję, że nie jest zbyt daleko: jeśli grep przeszukuje plik w /proc co prowadzi do zmapowanej pamięci, może się tak zdarzyć grep uderza w EOF w (losowej) pamięci i interpretuje następujące dane jako nową nazwę do wyszukania? Zacząłem czytać grep kod źródłowy, ale chyba nie zobaczę w nim zbyt wiele.
krork
1
@krork W niektórych starych systemach operacyjnych, takich jak CP / M, koniec pliku był sygnalizowany znakiem EOF. Ponieważ nowoczesne systemy plików śledzą rozmiar pliku, takie znaki nie są już używane.
John1024
2
Grepping /dev może nigdy się nie skończy, gdy grep zacznie skanować /dev/zero lub podobne. Nie jesteś pewien, czy takie pliki istnieją /proc lub /sys.
user2313067
1
@ user2313067 Dobry punkt! Podczas gdy GNU grep odmówi wyszukiwania /dev/zero, będzie szukać /dev/random na zawsze, chyba że się zatrzyma. Aktualizacja odpowiedzi.
John1024
Nie robię wiele z / proc lub / sys, ale ponieważ są to katalogi wirtualne, które mogą być aktualizowane w dowolnym momencie, możesz uzyskać nieoczekiwane / niepowtarzalne wyniki z wielu uruchomień. Oczywiście może się to zdarzyć również w przypadku zwykłych systemów plików, ale może to być trochę bardziej zaskakujące.
Joe