Obsługa Rur Bash

Czy ktoś wie jak bash radzi sobie z przesyłaniem danych przez rury?

cat file.txt | tail -20

Czy to polecenie wyświetla całą zawartość pliku.txt do bufora, który jest następnie odczytywany przez tail? Albo To polecenie, powiedzmy, wyświetla zawartość pliku.txt linia po linii, a następnie pauza w każdej linii do przetworzenia tail, a następnie poprosić o więcej danych?

Powodem, dla którego pytam jest to, że piszę program na urządzeniu wbudowanym, który zasadniczo wykonuje sekwencję operacji na pewnym fragmencie danych, gdzie wyjście jednej operacji jest wysyłane jako wejście następnej operacji. Chciałbym się dowiedzieć, jak linux (bash) sobie z tym radzi, więc proszę o ogólną odpowiedź, a nie konkretnie co się dzieje, gdy uruchamiam plik "cat.txt / tail -20".

Z góry dziękuję za odpowiedzi!

EDIT: Shog9 zwrócił uwagę na odpowiedni artykuł Wikipedii, To nie doprowadziło mnie bezpośrednio do artykułu, ale pomogło mi znaleźć to: http://en.wikipedia.org/wiki/Pipeline_%28Unix%29#Implementation które miałem informacje, których szukałem.


Przepraszam, że nie wyraziłem się jasno. Oczywiście używasz rury i oczywiście używasz stdin i stdout odpowiednich części polecenia. Założyłem, że to zbyt oczywiste, by to stwierdzić.

Pytam, jak to jest obsługiwane/realizowane. Ponieważ oba programy nie mogą działać jednocześnie, w jaki sposób dane są przesyłane ze standardowego wejścia na stdout? Co się stanie, jeśli pierwszy program generuje dane znacznie szybciej niż drugi? Czy system po prostu uruchamia pierwsze polecenie, dopóki nie zostanie zakończone lub jego bufor stdout jest pełny, a następnie przechodzi do następnego programu, i tak dalej w pętli, aż nie zostanie więcej danych do przetworzenia lub jest bardziej skomplikowany mechanizm?

Author: Fred Foo, 2008-08-21

3 answers

Postanowiłem napisać nieco bardziej szczegółowe wyjaśnienie.

"magia" tutaj leży w systemie operacyjnym. Oba programy uruchamiają się mniej więcej w tym samym czasie i uruchamiają się w tym samym czasie (system operacyjny przypisuje im kawałek czasu na procesor do uruchomienia), jak każdy inny jednocześnie uruchomiony proces na komputerze (w tym aplikacja terminalowa i jądro). Tak więc, zanim jakiekolwiek dane zostaną przekazane, procesy robią wszystko, co konieczne do inicjalizacji. W twoim przykładzie, tail parsuje argument '-20', a cat parsuje plik'.txt ' argument i otwarcie pliku. W pewnym momencie tail dotrze do punktu, w którym potrzebuje danych wejściowych i powie systemowi operacyjnemu, że czeka na dane wejściowe. W innym momencie (przed lub po, nie ma to znaczenia) cat rozpocznie przekazywanie danych do systemu operacyjnego za pomocą protokołu stdout. To przechodzi do bufora w systemie operacyjnym. Następnym razem tail dostaje kawałek czasu na procesorze po wprowadzeniu niektórych danych do bufor cat pobierze pewną ilość tych danych (lub ich całość), która pozostawia bufor w systemie operacyjnym. Gdy bufor jest pusty, w pewnym momencie tail będzie musiał poczekać, aż cat wyda więcej danych. Jeśli cat wyprowadza dane znacznie szybciej niż tail, bufor się rozszerzy. cat ostatecznie skończy wysyłać dane, ale tail nadal będzie przetwarzał, więc cat zamknie się, a tail przetworzy wszystkie pozostałe dane w buforze. System operacyjny będzie sygnalizować ogon gdy nie ma już przychodzących danych z EOF. Tail przetworzy pozostałe dane. W tym przypadku tail prawdopodobnie odbiera wszystkie dane do okrągłego bufora 20 linii, a gdy system operacyjny zasygnalizuje, że nie ma więcej przychodzących danych, zrzuca ostatnie dwadzieścia linii na własne wyjście, które po prostu wyświetla się w terminalu. Ponieważ tail jest znacznie prostszym programem niż cat, prawdopodobnie spędzi większość czasu czekając, aż cat umieści dane w bufor.

W systemie z wieloma procesorami oba programy nie będą po prostu współdzielić plasterki czasu na tym samym rdzeniu procesora, ale prawdopodobnie będą działać w tym samym czasie na oddzielnych rdzeniach.

Aby uzyskać więcej szczegółów, jeśli otworzysz jakiś monitor procesów (specyficzny dla systemu operacyjnego), taki jak 'top' w Linuksie, zobaczysz całą listę uruchomionych procesów, z których większość efektywnie wykorzystuje 0% procesora. Większość aplikacji, chyba że są one chrupanie danych, spędzają większość czasu nie robiąc nic. Jest to dobre, ponieważ pozwala innym procesom na nieskrępowany dostęp do procesora zgodnie z ich potrzebami. Odbywa się to zasadniczo na trzy sposoby. Proces może dostać się do instrukcji w stylu sleep (n), gdzie w zasadzie mówi jądro, aby czekało n milisekund przed podaniem mu innego plasterka czasu do pracy. Najczęściej program musi czekać na coś z innego programu, na przykład' ogon ' czekający na więcej danych do bufora. W w tym przypadku system operacyjny obudzi proces, gdy dostępnych będzie więcej danych. Wreszcie, jądro może uprzedzić proces w trakcie wykonywania, dając trochę czasu procesorowi innym procesom. 'cat' i 'tail' to proste programy. W tym przykładzie tail spędza większość czasu czekając na więcej danych w buforze, a cat spędza większość czasu czekając na system operacyjny, aby pobrać dane z dysku twardego. Wąskim gardłem jest prędkość (lub powolność) fizycznego medium że plik jest przechowywany. To odczuwalne opóźnienie, które możesz wykryć, gdy uruchamiasz to polecenie po raz pierwszy, to czas potrzebny do odczytu głowic na dysku twardym, aby szukać pozycji na dysku twardym, gdzie ' plik.txt ' jest. Jeśli uruchomisz polecenie po raz drugi, system operacyjny prawdopodobnie będzie miał zawartość pliku.txt buforowany w pamięci, a prawdopodobnie nie zobaczysz żadnego zauważalnego opóźnienia (chyba że plik.txt jest bardzo duży lub plik nie jest już buforowany.)

Większość operacji ty czy na komputerze są związane z IO, co oznacza, że zwykle czekasz na dane pochodzące z dysku twardego lub z urządzenia sieciowego itp.

 54
Author: postfuturist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-21 05:46:23

Shog9 odwołał się już do artykułu w Wikipedii, ale sekcja implementacji zawiera szczegóły, które chcesz. Podstawową implementacją jest bufor Ograniczony.

 1
Author: David Schlosnagle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-21 01:45:20

Cat wydrukuje dane do standard out, co zdarza się przekierowywać do standard in of tail. Można to zobaczyć na stronie podręcznika bash.

Innymi słowy, nie ma pauzowania, tail jest tylko odczytem ze standardowego wejścia, a cat tylko zapisem do standardowego wyjścia.

 0
Author: Mike Stone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-21 00:29:00