Co robi symbol rury linuxowej „|”? [duplikować]

23

Oto polecenie sortujące pliki w folderze w odwrotnej kolejności

ls | sort -r

Co robi |symbol w tym poleceniu?

To, czego tak naprawdę szukam, to wyjaśnienie potoków dla początkujących na Linuksie na wysokim poziomie (łatwe do zrozumienia). Widzę inne pytania dotyczące potoków tutaj na Superużytkowniku, ale nic, co nie daje odpowiedzi, która wyjaśnia w prosty sposób, co robią i czym różnią się od przekierowania ( symbol >lub <).

ccalvert
źródło
7
Nie ma to nic wspólnego z Linuksem (który jest jądrem). Ogólnie rzecz biorąc, rury są sposobem na przekierowanie wejścia / wyjścia, w powłoce takiej jak bash nie jest inaczej. Jedyną szczególną rzeczą w a |jest to, że nie używa ona nazwy, dane wyjściowe z polecenia z lewej strony są przekazywane bezpośrednio do danych wejściowych dla polecenia z prawej strony potoku.
Andon M. Coleman
Aby zapoznać się z lekcją
Fredrik Pihl,
ls -1r(Zwróć uwagę na argument numer jeden) powinien dać podobny wynik ls | sort -r.
Ivan Chau
Lubię to wyjaśniać w ten sposób: potok pobiera dane wyjściowe jednego polecenia i czyni je użytecznymi dla następnego polecenia. Na przykład możesz to zrobić cat /somefile | grep cool. Spowoduje to, że wyjdzie z jakiegoś pliku i udostępni go do grep, a następnie grep wydrukuje wszystkie wiersze ze słowem cool.
JohnDoea

Odpowiedzi:

26

Poniższe zostało nieco uproszczone, aby pomóc nowym użytkownikom.

Po pierwsze, konieczne jest zrozumienie pojęcia standardowego wejścia i standardowego wyjścia.

W systemie Linux i innych systemach operacyjnych typu UNIX każdy proces ma standardowe wejście ( stdin) i standardowe wyjście ( stdout). Zazwyczaj jest stdinto klawiatura i stdoutokno ekranu lub terminala.

Więc kiedy uruchomisz ls, wyrzuci swoje wyjście do stdout. Jeśli nie zrobisz nic więcej, przejdzie do ekranu lub okna terminala i wyświetlisz go.

Teraz niektóre polecenia Linuksa współdziałają z użytkownikiem i używają stdindo tego celu, a edytor tekstowy jest jednym z nich. Czyta z, stdinaby zaakceptować naciśnięcia klawiszy, robić rzeczy, a następnie zapisuje różne rzeczy stdout.

Istnieją jednak również nieinteraktywne lub „filtrujące” polecenia, które NIE działają interaktywnie, ale wymagają dużej ilości danych. Te polecenia zabiorą wszystko stdin, zrób coś, a następnie wrzućstdout

Spójrzmy na inne polecenie o nazwie du- oznacza użycie dysku. du /usr, na przykład wydrukuje (aby stdoutpolubić każde inne polecenie Linuksa) listę każdego pliku w tym katalogu i jego rozmiar:

# du /usr
2312    /usr/games
124     /usr/lib/tc
692     /usr/lib/rygel-1.0
400     /usr/lib/apt/methods
40      /usr/lib/apt/solvers
444     /usr/lib/apt
6772    /usr/lib/gnash

Jak widać od samego początku nietoperz, nie jest sortowany i prawdopodobnie chcesz go posortować według wielkości.

sortjest jednym z tych poleceń „filtrujących”, które wezmą kilka rzeczy stdini posortują je.

Więc jeśli to zrobimy:

# du /usr | sort -nr

otrzymujemy to, co jest nieco lepsze:

4213348 /usr
2070308 /usr/lib
1747764 /usr/share
583668  /usr/lib/vmware
501700  /usr/share/locale
366476  /usr/lib/x86_64-linux-gnu
318660  /usr/lib/libreoffice
295388  /usr/lib/vmware/modules
290376  /usr/lib/vmware/modules/binary
279056  /usr/lib/libreoffice/program
216980  /usr/share/icons

I możesz teraz zobaczyć, że „potok” łączy stdoutjedno polecenie stdinz drugim. Zazwyczaj używasz go w takich sytuacjach, w których chcesz filtrować, sortować lub w inny sposób manipulować wyjściem polecenia. Mogą być kaskadowane, jeśli chcesz przetwarzać dane wyjściowe za pomocą wielu poleceń typu filtr.

Jeśli wpiszesz sortsam, nadal będzie próbował czytać stdin. Ponieważ stdinjest podłączony do klawiatury, będzie czekał na wpisanie i przetworzenie rzeczy do momentu naciśnięcia klawisza Control-D. Nie wyświetli monitu, ponieważ tak naprawdę nie jest przeznaczony do interaktywnego używania.

Program może stwierdzić, czy stdinjest interaktywny, czy nie, więc niektóre programy mogą działać inaczej, jeśli wydasz je samodzielnie lub na końcu potoku.

Ponadto, potokowanie programu, który działa tylko interaktywnie, na przykład vi, spowoduje, że będziesz miał zły czas.

Rurki różnią się od przekierowania tym, że dane są losowo przenoszone z jednego polecenia do drugiego, ale nie są nigdzie przechowywane. W powyższym przykładzie dudane wyjściowe nie są nigdzie przechowywane. W większości przypadków nie chcesz tego z potokami, ponieważ powodem użycia potoków jest w pewien sposób przetworzenie wyniku polecenia - ale istnieje polecenie, teektóre pozwala ci mieć ciasto i je zjeść, to będzie skopiuj to, co otrzyma, stdindo obu stdoutplików i wybranego pliku. Możesz to również zrobić bashz tajemniczą składnią obejmującą ampersands i nawiasy, o których nie wiem.

LawrenceC
źródło
Pamiętaj, że nie jest to unikalne w przypadku Linuksa, a nawet POSIX. Robi to większość (wszystkich?) Powłok w systemie Windows. I prawdopodobnie inne systemy operacyjne.
Bob
Wiem, że koncepcja stdini stdoutjest inna pod Windows niż pod Linuksem, choć prawdopodobnie nie bardzo z punktu widzenia Windows cmd.exelub Powershell.
LawrenceC
Jestem ciekawy, jak to się różni - czy mógłbyś to wyjaśnić? Może na czacie, jeśli komentarze nie są dobrym miejscem na to.
Bob
1
Programy Win32 zdecydowanie mają standardowe wejście i wyjście. Na przykład możesz odzyskać standardowe wejście, wyjście lub uchwyt błędu swojego procesu za pomocą funkcji Win32 GetStdHandle(). Przekierowanie standardowych strumieni spawnowanego procesu [podrzędnego] za pomocą platformy .NET jest banalne, co moim zdaniem odwzorowuje na funkcje Win32 (ale nie jestem tego w 100% pewien - nie jestem programistą Win32).
Bob
1
Ach, tutaj jest odpowiednik Win32, ustawiając odpowiednie parametry w STARTUPINFOstrukturze dla CreateProcess().
Bob
27

Jeśli nie masz nic przeciwko przekierowaniu danych wyjściowych i wejściowych, wyjaśnienie jest naprawdę dość proste.

Command1 | Command2

robi to samo co

Command1 > tempfile
Command2 < tempfile

ale bez tempfile. Wyjście Command1jest bezpośrednio podłączone do wejścia, Command2a przesyłanie odbywa się w pamięci.

Daniel B.
źródło
Mogę się mylić, ale myślę, że plik tymczasowy istnieje nawet w składni potoku. Po prostu nie ma nazwy.
Taemyr
3
Nie. Podczas przesyłania potokiem danych wyjściowych z jednego polecenia do danych wejściowych innego polecenia nie są zaangażowane żadne operacje systemu plików.
Daniel B
1
Choć pod DOS (i najprawdopodobniej Windows), plik temp jest utworzona przez rury. Nie * nix, ale nic nie warte różnicy.
Jeremy J Starcher
Jestem prawie pewien, że to nie jest poprawne. Monitor procesu zgłasza brak CreateFilelub WriteFilewezwania do poparcia roszczenia. / edit: Oczywiście dotyczy to części Windows.
Daniel B,
3

Naprawdę, jeśli chcesz wiedzieć, co robią potoki i różnicę między> a |, przejdź do katalogu z dużą ilością plików i

z terminala ls vs ls | more (lub robienie tego z systemu Windows za pomocą DIR i DIR | MORE)

Jeśli użyłeś> more, zobaczysz, że tworzy on plik o nazwie „more” zamiast wysyłać dane wyjściowe ls do polecenia „more”. Więc jeśli ktoś zrobił> więcej, prawdopodobnie byłby to błąd, nie zrobiłby> więcej niż zrobiłbyś> file1. Więcej to dobrze znane polecenie.

<Jak the> służy również do łączenia polecenia i pliku, a nie polecenia z poleceniem. Ale podczas gdy>> wysyła dane wyjściowe polecenia do pliku, <wysyła plik jako dane wejściowe do polecenia. Rzadko używam <jak zwykle używam cat file1 | wysłać wynik pliku do polecenia.

$ grep a <plik1 abc

plik $ cat1 | grep a abc

grep z 2 parametrami ma postać pliku wzorca grep. grep z jednym parametrem jest wzorem grep. Możesz wysłać plik, przesyłając do niego zawartość pliku lub używając <. Jeśli używasz <, najpierw wpisz nazwę polecenia, a następnie nazwę pliku <polecenie <plik. Jeśli używasz | do potokowania zawartości pliku używasz cat file1 | dowództwo.

Również wiele poleceń pobiera plik jako dane wejściowe, więc grep plik1 będzie działał, podobnie jak plik cat1 | grep a i grep a <plik1.

Robiłem potoki (|) i> na DOSie nawet 15 lat temu.

Podsumowując, jak | różni się od <i> - potok znajduje się między 2 poleceniami <i> siedzą między poleceniem a plikiem. > Jest wyprowadzane do pliku. <Jest wprowadzane z pliku.

barlop
źródło
3

Znak potoku ( |) łączy dane wyjściowe jednego programu z danymi wejściowymi innego programu.

W tym przykładzie echowypisuje słowo helloi wc -cwykonuje liczbę wprowadzonych znaków:

echo hello | wc -c
bbaassssiiee
źródło
Myślę, że powinieneś natychmiast powiedzieć, że echo wyświetli „hello \ n”. Nie każesz OP się uczyć, mówisz to każdemu, kto przeczyta twoją odpowiedź. Po co pomnażać tę stratę czasu?
Rodrigo,
Dzięki za opinie skróciłem swoją odpowiedź.
bbaassssiiee
2

Aby to zrozumieć, spróbuj sam:

sort -r

Teraz zwisasz kursorem i nic nie robi. Co się stanie, jeśli wpiszesz jakieś dane?

1
2
3
5
4

Nadal nic, prawda? Teraz naciśnij ctrl + D

5
4
3
2
1

Czym więc jest sortowanie, pobiera dane wejściowe (to, co wpisałeś), coś z tym robi (sortuje) i zwraca jako wynik. lsKomenda nie bierze wejście, to tylko generuje dane wyjściowe. Symbol potoku pobiera dane wyjściowe lsi podaje je jako dane wejściowe do sortpolecenia.

>nie podaje danych wyjściowych do programu, ale przechowuje dane wyjściowe jako plik. <używa pliku jako danych wejściowych.

jornane
źródło