Dlaczego grep nie używa tu potoku?

18

Mam następujące polecenie:

find / -name libGL.so.1

Który zwraca wiele wierszy z „Odmowa zezwolenia”. Chcę wykluczyć takie wiersze, więc dodałem następujące:

find / -name libGL.so.1 | grep -v 'denied'

Ale wynik jest taki sam - mój grep -v 'denied'nie odfiltrowuje wierszy Permission denied. Próbowałem wielu odmian, przejrzałem samouczki grep, ale nie mogę rozwiązać problemu. Jakieś sugestie?

modulitos
źródło

Odpowiedzi:

44

To nie ma nic wspólnego grep- to dlatego, że potok |przekierowuje standardowy strumień wyjściowy, stdoutpodczas gdy Permission deniedkomunikaty znajdują się w standardowym strumieniu błędów stderr. Możesz osiągnąć pożądany wynik, łącząc strumienie za pomocą 2>&1(przekieruj strumień, którego deskryptorem pliku jest 2strumień, którego deskryptorem jest plik 1), aby można było stderrrównież stdoutprzesłać strumieniowo do wejścia polecenia grep

find / -name libGL.so.1 2>&1 | grep -v 'denied'

ale bardziej zwyczajnie byłoby po prostu stderrcałkowicie odrzucić , przekierowując go na/dev/null

find / -name libGL.so.1 2>/dev/null

Używanie | & zamiast 2> i 1 |

Jeśli spojrzysz na stronę podręcznika użytkownika Bash, prawdopodobnie zauważysz ten błąd:

Jeśli |&jest używany, standardowy błąd polecenia jest połączony ze standardowym wejściem polecenia 2 przez potok; jest skrótem od 2>&1 |.

Możesz więc także użyć tego konstruktu, jeśli chcesz dołączyć do STDERR i STDOUT:

find / -name libGL.so.1 |& grep -v 'denied'
steeldriver
źródło
3
Dodatkowa uwaga na temat ich łączenia: Jeśli z jakiegoś dziwnego powodu plik istnieje w /foo/bar/denied/libGL.so.1, połączenie, stdouta stderr następnie filtrowanie ukryłoby wynik
Izkata
5

Twoje polecenie powinno brzmieć:

find / -name libGL.so.1 2>/dev/null

Find narzeka na uprawnienia do standardowego błędu (fd2). Aby wyeliminować te linie, przekieruj (>) standard do segmentu bitów (/ dev / null).

Korzeń węża
źródło
4

Linie „odmowa uprawnień” idą do strumienia stderr (błąd standardowy), ale przepuszczasz stdout (wyjście standardowe) przez grep.

Możesz całkowicie przekierować stderr za pomocą

find / -name libGL.so.1 2> /dev/null
Andrew McGuinness
źródło
2

Czy próbowałeś wywołać polecenie za pomocą sudo ?

sudo find / -name libGL.so.1

Jeśli nadal wyświetla komunikat, użyj wspomnianego już przekierowania stderr (fd = 2) do nirwany (/ dev / null) :

sudo find / -name libGL.so.1 2> /dev/null

Więcej pomysłów tutaj , powodzenia!

manamana
źródło