Jest to prawdopodobnie w wielu często zadawanych pytaniach - zamiast używać:
cat file | command
(co nazywa się bezużytecznym użyciem kota), poprawny sposób powinien być:
command < file
W drugim, „poprawnym” sposobie - system operacyjny nie musi generować dodatkowego procesu.
Pomimo tego, z 2 powodów nadal używałem bezużytecznego kota.
bardziej estetyczny - lubię, gdy dane przesuwają się równomiernie tylko od lewej do prawej. I łatwiej wymienić
cat
na coś innego (gzcat
,echo
...), dodać 2nd plik lub wstawić nowy filtr (pv
,mbuffer
,grep
...).„Czułem”, że w niektórych przypadkach może być szybciej. Szybciej, ponieważ są 2 procesy, pierwszy (
cat
) odczytuje, a drugi cokolwiek. Mogą działać równolegle, co czasami oznacza szybszą realizację.
Czy moja logika jest poprawna (z drugiego powodu)?
źródło
cat
jest potokiem tożsamości . Przesyła tylko swoje dane wejściowe do swojego wyjścia. Jeśli drugi program w łańcuchu może pobierać dane wejściowe z tego samego argumentu, do którego przekazujeszcat
(lub ze standardowego wejścia, jeśli nie przekażesz żadnego argumentu), tocat
jest absolutnie bezużyteczny i powoduje tylko rozwidlenie dodatkowego procesu i dodatkowy potok Utworzony.-
, jest to potok tożsamości. Kiedy ma więcej niż jeden argument nazwy pliku bez myślnika, staje się czymś więcej niż potokiem identyfikacyjnym i zaczyna służyć prawdziwemu celowi.<file command1 | command2
, chociaż nie byłoby zgody co do estetyki.Odpowiedzi:
O nagrodzie nie wiedziałem, aż do dzisiaj, kiedy jakiś nowicjusz próbował przypisać mi UUOC za jedną z moich odpowiedzi. To był
cat file.txt | grep foo | cut ... | cut ...
. Dałem mu trochę do zrozumienia i dopiero po tym, gdy to zrobiłem, odwiedziłem link, który mi podał, odnosząc się do pochodzenia nagrody i praktyki. Dalsze poszukiwania doprowadziły mnie do tego pytania. Nieco niestety, pomimo świadomego namysłu, żadna z odpowiedzi nie zawierała mojego uzasadnienia.Nie chciałem być defensywny, odpowiadając mu. W końcu w moich młodszych latach napisałbym komendę tak,
grep foo file.txt | cut ... | cut ...
ponieważ za każdym razem, gdy robisz częste singlegrep
, uczysz się umiejscowienia argumentu plik i jest już wiadomo, że pierwszy to wzorzec, a następne to nazwy plików.Był to świadomy wybór,
cat
gdy odpowiadałem na to pytanie, częściowo z powodu „dobrego smaku” (według słów Linusa Torvaldsa), ale głównie z nieodpartego powodu funkcji.Ten ostatni powód jest ważniejszy, więc wypowiem go jako pierwszy. Kiedy oferuję rurociąg jako rozwiązanie, oczekuję, że będzie można go ponownie wykorzystać. Jest całkiem prawdopodobne, że rurociąg zostałby dodany na końcu lub połączony z innym rurociągiem. W takim przypadku posiadanie argumentu plikowego w celu grepa psuje możliwość ponownego użycia i całkiem możliwe, że zrobi to po cichu bez komunikatu o błędzie, jeśli argument plik istnieje. I. e.
grep foo xyz | grep bar xyz | wc
poda, ile wierszyxyz
zawiera,bar
podczas gdy spodziewasz się liczby wierszy zawierających obafoo
ibar
. Konieczność zmiany argumentów na polecenie w potoku przed jego użyciem jest podatna na błędy. Dodaj do tego możliwość cichych niepowodzeń, a stanie się to szczególnie podstępną praktyką.Ten pierwszy powód również nie jest nieważny, ponieważ wiele „ dobrego smaku ” jest po prostu intuicyjnym, podświadomym uzasadnieniem takich rzeczy, jak ciche niepowodzenia powyżej, o których nie możesz pomyśleć w momencie, gdy jakaś osoba potrzebująca edukacji mówi: „ale tak nie jest ten kot bezużyteczny ”.
Postaram się jednak również uświadomić poprzedni powód „dobrego smaku”, o którym wspomniałem. Powód ten ma związek z ortogonalnym duchem projektowania Uniksa.
grep
nie robicut
ils
nie robigrep
. Dlatego przynajmniejgrep foo file1 file2 file3
jest sprzeczne z duchem projektowania. Jest to ortogonalnecat file1 file2 file3 | grep foo
. Togrep foo file1
tylko szczególny przypadekgrep foo file1 file2 file3
, a jeśli nie traktujesz go tak samo, przynajmniej zużywasz cykle zegara mózgowego, próbując uniknąć bezużytecznej nagrody dla kota.To prowadzi nas do argumentu, który
grep foo file1 file2 file3
jest konkatenacją icat
konkatenacją, więc jest to właściwe,cat file1 file2 file3
ale ponieważcat
nie jest konkatenowane,cat file1 | grep foo
dlatego naruszamy duchacat
i wszechmocnego Uniksa. Cóż, gdyby tak było, Unix potrzebowałby innego polecenia, aby odczytać wyjście z jednego pliku i wypluć go na standardowe wyjście (nie paginować go ani cokolwiek po prostu spluwać na standardowe wyjście). Miałbyś więc sytuację, w której mówiszcat file1 file2
lub mówisz,dog file1
i sumiennie pamiętaj, aby uniknąćcat file1
otrzymania nagrody, jednocześnie unikając,dog file1 file2
ponieważ mam nadzieję, że projektdog
spowoduje błąd, jeśli określono wiele plików.Miejmy nadzieję, że w tym momencie sympatyzujesz z projektantami Uniksa za to, że nie dołączali oddzielnego polecenia wypluwania pliku na standardowe wyjście, jednocześnie nadając mu nazwę
cat
do konkatenacji, zamiast nadawać mu inną nazwę.<edit>
usunięto niepoprawne komentarze<
w rzeczywistości<
jest skutecznym narzędziem bez kopiowania do wypluwania pliku na standardowe wyjście, które można umieścić na początku potoku, więc projektanci Uniksa dodali coś specjalnie do tego celu</edit>
Kolejne pytanie brzmi: dlaczego ważne jest, aby polecenia, które po prostu wypluwają plik lub konkatenację kilku plików na standardowe wyjście, bez dalszego przetwarzania? Jednym z powodów jest unikanie posiadania każdego pojedynczego polecenia Uniksa, które działa na standardowym wejściu, aby wiedzieć, jak przeanalizować co najmniej jeden argument pliku wiersza poleceń i użyć go jako wejścia, jeśli istnieje. Drugim powodem jest uniknięcie konieczności pamiętania przez użytkowników: (a) gdzie znajdują się argumenty nazwy pliku; i (b) unikaj cichego błędu rurociągu, jak wspomniano powyżej.
To prowadzi nas do tego, dlaczego
grep
ma dodatkową logikę. Uzasadnieniem jest umożliwienie użytkownikowi płynnego posługiwania się poleceniami, które są używane często i samodzielnie (a nie jako potok). Jest to niewielki kompromis ortogonalności w celu znacznego zwiększenia użyteczności. Nie wszystkie polecenia powinny być zaprojektowane w ten sposób, a polecenia, które nie są często używane, powinny całkowicie unikać dodatkowej logiki argumentów plikowych (pamiętaj, że dodatkowa logika prowadzi do niepotrzebnej kruchości (możliwość błędu)). Wyjątkiem jest dopuszczenie argumentów plikowych, takich jak w przypadkugrep
. (Nawiasem mówiąc, zwróć uwagę, żels
ma zupełnie inny powód, aby nie tylko akceptować, ale prawie wymagać plików argumentów)Wreszcie, co można było zrobić lepiej, to gdyby takie wyjątkowe polecenia, jak
grep
(ale niekonieczniels
), generowały błąd, jeśli standardowe wejście jest również dostępne, gdy podano argumenty pliku.źródło
grep
jest wywoływany z wieloma nazwami plików, poprzedza znalezione wiersze nazwą pliku, w którym został znaleziony (chyba że wyłączysz to zachowanie). Może również raportować numery wierszy w poszczególnych plikach. Jeśli używasz tylkocat
do podawaniagrep
, tracisz nazwy plików, a numery wierszy są ciągłe we wszystkich plikach, a nie w każdym pliku. Dlatego istnieją powody, dla których trzebagrep
obsługiwać wiele plików,cat
których nie można obsłużyć. Przypadki jednoplikowe i zerowe to po prostu szczególne przypadki ogólnego stosowania wielu plikówgrep
.< file command1 ...
. Chociaż konwencjonalne położenie operatorów przekierowania we / wy znajduje się po nazwie polecenia i jego argumentach, jest to tylko konwencja, a nie obowiązkowe umieszczenie.<
Musi poprzedzać nazwę pliku. Tak, jest to blisko doskonałej symetrii pomiędzy>output
i<input
przekierowań:<input command1 -opt 1 | command2 -o | command3 >output
.cat
jest to bezużyteczne. Nie jestcat
to bezużyteczne; chodzi o to, że określony konstrukt nie wymaga użyciacat
. Jeśli chcesz, pamiętaj, że jest to UUoC (bezużyteczne użyciecat
), a nie UoUC (użycie bezużytecznegocat
). Jest wiele sytuacji, w którychcat
należy użyć właściwego narzędzia; Nie mam problemu z używaniem go, gdy jest to właściwe narzędzie do użycia (i rzeczywiście, wspomnę o przypadku w mojej odpowiedzi).cat
w potoku może nie być wielkim problemem w zależności od danych, ale gdy jest używany jako środowisko programistyczne, może być absolutnie konieczne zaimplementowanie tych krytycznych dla wydajności rzeczy; zwłaszcza gdy mamy do czynienia zbash
którym, pod względem osiągów, jest jak koło w kształcie prostokąta (w porównaniu doksh
zresztą. Mówię tu nawet 10x wolniej - bez żartów). Ci nie chcą zoptymalizować swoje widelce (i nie tylko tego) gdy ma do czynienia z większymi skryptów lub ogromnych pętli.Nie!
Przede wszystkim nie ma znaczenia, gdzie w poleceniu następuje przekierowanie. Więc jeśli podoba Ci się przekierowanie na lewo od polecenia, to w porządku:
jest taki sam jak
Po drugie, gdy używasz potoku , występuje n + 1 procesów i podpowłoka. Jest zdecydowanie wolniejszy. W niektórych przypadkach n byłoby równe zero (na przykład, gdy przekierowujesz do wbudowanej powłoki), więc używając
cat
, dodajesz nowy proces całkowicie niepotrzebnie.Ogólnie rzecz biorąc, za każdym razem, gdy używasz fajki, warto poświęcić 30 sekund na sprawdzenie, czy możesz ją wyeliminować. (Ale prawdopodobnie nie warto zajmować więcej niż 30 sekund.) Oto kilka przykładów, w których rury i procesy są często używane niepotrzebnie:
Zapraszam do edycji, aby dodać więcej przykładów.
źródło
< cat grep dog
jest wymyślnym przykładem pokazującym, że nie możesz łatwo odróżnić pliku wejściowego, polecenia który otrzymuje dane wejściowe i argumenty polecenia.stdout=$(foo bar -exec baz <qux | ENV=VAR quux)
. P. Czy ma<qux
zastosowanie dofoo
, lub dobaz
którego jest-exec
celfoo
? A. Dotyczyfoo
, ale może wydawać się niejednoznaczny. W tym przypadku wstawianie<qux
przedfoo
jest wyraźniejsze, choć mniej powszechne i jest analogiczne do wstawiania na końcuENV=VAR quux
.<"cat" grep dog
jest tam łatwiejszy do odczytania. (Zwykle jestem zwolennikiem białych znaków, ale ten konkretny przypadek jest bardzo wyjątkiem).Nie zgadzam się z większością przypadków nadmiernie zadowolonej z siebie nagrody UUOC, ponieważ podczas nauczania kogoś innego
cat
jest wygodnym miejscem na dowolne polecenie lub skomplikowany potok poleceń, które generują dane wyjściowe odpowiednie dla omawianego problemu lub zadania.Jest to szczególnie prawdziwe w witrynach takich jak Stack Overflow, ServerFault, Unix i Linux lub w dowolnej witrynie SE.
Jeśli ktoś konkretnie pyta o optymalizację lub jeśli masz ochotę dodać dodatkowe informacje na jej temat, to świetnie, porozmawiaj o tym, że korzystanie z cat jest nieefektywne. Ale nie krytykuj ludzi, ponieważ zdecydowali się dążyć do prostoty i łatwości zrozumienia w swoich przykładach, zamiast patrzeć na mnie, jak fajnie-jestem! złożoność.
Krótko mówiąc, ponieważ kot nie zawsze jest kotem.
Również dlatego, że większość ludzi, którzy lubią nagradzać UUOC, robi to, ponieważ bardziej zależy im na tym, by pokazać, jak `` sprytni '' są, niż o pomaganie lub nauczanie ludzi. W rzeczywistości pokazują, że są prawdopodobnie kolejnym nowicjuszem, który znalazł mały kij do pokonania swoich rówieśników.
Aktualizacja
Oto kolejny UUOC, który zamieściłem w odpowiedzi na https://unix.stackexchange.com/a/301194/7696 :
Pedanci UUOC powiedzieliby, że to jest UUOC, ponieważ łatwo można ustawić
$filter
domyślny pusty ciąg i miećif
instrukcję,filter='| grep -v "^$"'
ale IMO, nie osadzając znaku potoku w$filter
, to „bezużyteczne”cat
służy niezwykle użytecznemu celowi samodokumentowania faktu że$filter
tenprintf
wiersz nie jest tylko kolejnym argumentemsqlplus
, jest to opcjonalny filtr wyjściowy wybierany przez użytkownika.Jeśli nie ma żadnej potrzeby, aby mieć wiele opcjonalnych filtrów wyjściowych, przetwarzanie może po prostu opcja dołączania
| whatever
do$filter
tak często jak potrzeba - jeden dodatkowycat
w rurociągu nie będzie bolało cokolwiek lub powoduje zauważalny spadek wydajności.źródło
==
środku[ ]
nie jest określony przez POSIX i nie wszystkie implementacje go akceptują. Standardowy operator jest sprawiedliwy=
.Z wersją UUoC,
cat
musi odczytać plik do pamięci, a następnie zapisać go do rury, a komenda musi odczytać dane z rury, więc jądro musi skopiować cały plik trzy razy, podczas gdy w przekierowanego wypadku jądro musi tylko raz skopiować plik. Szybciej jest zrobić coś raz, niż zrobić to trzy razy.Za pomocą:
jest zupełnie innym i niekoniecznie bezużytecznym zastosowaniem
cat
. Nadal jest bezużyteczne, jeśli polecenie jest standardowym filtrem, który akceptuje zero lub więcej argumentów nazw plików i przetwarza je po kolei. Rozważtr
polecenie: jest to czysty filtr, który ignoruje lub odrzuca argumenty nazwy pliku. Aby przesłać do niego wiele plików, musisz użyć,cat
jak pokazano. (Oczywiście istnieje osobna dyskusja, że projekttr
nie jest zbyt dobry; nie ma prawdziwego powodu, dla którego nie mógł zostać zaprojektowany jako standardowy filtr). Może to również być poprawne, jeśli chcesz, aby polecenie traktowało wszystkie dane wejściowe jako pojedynczy plik, a nie jako wiele oddzielnych plików, nawet jeśli polecenie zaakceptowałoby wiele oddzielnych plików: na przykładwc
jest takim poleceniem.Jest to
cat single-file
przypadek, który jest bezwarunkowo bezużyteczny.źródło
W obronie kota:
Tak,
lub
jest bardziej wydajne, ale wiele wywołań nie ma problemów z wydajnością, więc nie przejmujesz się.
przyczyny ergonomiczne:
Jesteśmy przyzwyczajeni do czytania od lewej do prawej, więc polecenie takie jak
jest trywialne do zrozumienia.
musi przeskoczyć proces1, a następnie czytać od lewej do prawej. Można to wyleczyć:
wygląda jakoś, jakby była strzałka skierowana w lewo, gdzie nic nie ma. Bardziej zagmatwany i wyglądający jak fantazyjny cytat jest:
a generowanie skryptów jest często procesem iteracyjnym,
gdzie widzisz swój postęp krok po kroku, podczas gdy
nawet nie działa. Proste sposoby są mniej podatne na błędy, a ergonomiczne wyszukiwanie poleceń jest proste dzięki cat.
Innym tematem jest to, że większość ludzi była narażona na działanie> i <jako operatorów porównania, na długo przed użyciem komputera i podczas korzystania z komputera jako programistów, są one znacznie częściej narażone na takie działanie.
Porównywanie dwóch operandów z <i> jest przeciwstawne, co oznacza
Obawiałem się, że pierwszy raz użyłem <do przekierowania danych wejściowych
może oznaczać to samo co
i jakoś nadpisuję mój skrypt a.sh. Może jest to problem dla wielu początkujących.
rzadkie różnice
Ta ostatnia może być używana bezpośrednio w obliczeniach.
Oczywiście <może być tutaj również użyte zamiast parametru pliku:
ale kogo to obchodzi - 15k?
Gdybym od czasu do czasu napotkał jakieś problemy, z pewnością zmieniłbym swój nawyk wzywania kota.
Podczas używania bardzo dużych lub wielu, wielu plików unikanie cat jest w porządku. W większości pytań użycie kota jest ortogonalne, nie na temat, a nie problem.
Rozpoczynanie tych bezużytecznych dyskusji o kotach na co drugi temat powłoki jest tylko irytujące i nudne. Rób sobie życie i czekaj na swoją minutę sławy, odpowiadając na pytania dotyczące wydajności.
źródło
file > a.sh
jest sam w sobie wart przeczytania tego :) Dzięki za podzielenie się!cat file | wc -c
,wc
musi odczytać stdin, dopóki EOF, liczenie bajtów. Ale w tymwc -c < file
przypadku po prostu stdin stdin, dowiaduje się, że jest to zwykły plik i wyświetla st_size zamiast czytać jakiekolwiek wejście. W przypadku dużego pliku różnica w wydajności byłaby wyraźnie widoczna.Dodatkowym problemem jest to, że rura może bezgłośnie maskować podpowłokę. W tym przykładzie, będę wymieniać
cat
zecho
, ale ten sam problem istnieje.Możesz spodziewać
x
się, że zawierafoo
, ale tak nie jest.x
Ty zestaw był w podpowłoce zrodził wykonaćwhile
pętlę.x
w powłoce, która uruchomiła potok, ma niepowiązaną wartość lub nie jest w ogóle ustawiona.W bash4 możesz skonfigurować niektóre opcje powłoki, aby ostatnie polecenie potoku było wykonywane w tej samej powłoce, co ta, która uruchamia potok, ale możesz spróbować tego
i
x
jest ponownie lokalna dlawhile
podpowłoki '.źródło
shopt -s lastpipe
unikać tworzenia podpowłoki.Jako ktoś, kto regularnie zwraca uwagę na to i wiele innych antywzorów programowania powłoki, czuję się zobowiązany, z opóźnieniem, rozważyć.
Skrypt powłoki jest w dużej mierze językiem kopiuj / wklej. Dla większości ludzi, którzy piszą skrypty powłoki, nie uczą się języka; jest to po prostu przeszkoda, którą muszą pokonać, aby kontynuować pracę w języku (językach), które w rzeczywistości są nieco zaznajomione.
W tym kontekście uważam, że propagowanie różnych anty-wzorców skryptów powłoki jest destrukcyjne, a nawet destrukcyjne. Idealnie byłoby, gdyby kod, który ktoś znalazł w Stack Overflow, był możliwy do skopiowania / wklejenia do ich środowiska z minimalnymi zmianami i niepełnym zrozumieniem.
Wśród wielu zasobów skryptów powłoki w sieci, Stack Overflow jest niezwykłe, ponieważ użytkownicy mogą pomóc w kształtowaniu jakości witryny, edytując pytania i odpowiedzi w witrynie. Jednak edycje kodu mogą być problematyczne ponieważ łatwo jest wprowadzić zmiany, które nie były zamierzone przez autora kodu. Dlatego mamy tendencję do zostawiania komentarzy, aby zasugerować zmiany w kodzie.
UUCA i powiązane komentarze antywzorcowe są przeznaczone nie tylko dla autorów kodu, który komentujemy; są one tak samo emptor zastrzeżenie , aby pomóc czytelnikom w miejscu stać się świadomi problemów w kodzie one znaleźć tutaj.
Nie możemy mieć nadziei na osiągnięcie sytuacji, w której żadne odpowiedzi na Stack Overflow nie zalecają bezużytecznych
cat
s (lub zmiennych niecytowanych lubchmod 777
wielu innych plag anty-wzorców), ale możemy przynajmniej pomóc w edukacji użytkownika, który ma zamiar skopiować / wklej ten kod do najbardziej wewnętrznej ścisłej pętli ich skryptu, który jest wykonywany miliony razy.Jeśli chodzi o przyczyny techniczne, tradycyjna mądrość jest taka, że powinniśmy starać się minimalizować liczbę procesów zewnętrznych; jest to nadal dobra ogólna wskazówka podczas pisania skryptów powłoki.
źródło
cat
wiąże się z wieloma dodatkowymi przełącznikami kontekstu i przepustowością pamięci (i zanieczyszczeniem pamięci podręcznej L3 dodatkowymi kopiami danych wcat
buforze odczytu i buforach potoków). Zwłaszcza na dużej maszynie wielordzeniowej (takiej jak wiele konfiguracji hostingu) przepustowość pamięci podręcznej / pamięci jest zasobem współdzielonym.bzip2
igzip
kompresja są bardzo powolne w porównaniu z ilością narzutówcat
do tego samego (z maszyną bezczynną). Trudno jest odczytać tabele (zawijanie wiersza w środku liczby?).sys
czas znacznie się wydłuża, ale wciąż mały w porównaniu z użytkownikiem czy rzeczywistą?Często używam
cat file | myprogram
w przykładach. Czasami jestem oskarżany o bezużyteczne wykorzystanie kota ( http://porkmail.org/era/unix/award.html ). Nie zgadzam się z następujących powodów:Łatwo jest zrozumieć, co się dzieje.
Czytając polecenie UNIX, oczekujesz polecenia, po którym następują argumenty, po których następuje przekierowanie. Możliwe jest umieszczenie przekierowania w dowolnym miejscu, ale jest to rzadko spotykane - w ten sposób ludzie będą mieli trudniej przeczytać przykład. wierzę
jest łatwiejszy do odczytania niż
Jeśli przeniesiesz przekierowanie na początek, dezorientujesz ludzi, którzy nie są przyzwyczajeni do tej składni:
a przykłady powinny być łatwe do zrozumienia.
Łatwo to zmienić.
Jeśli wiesz, że program może czytać
cat
, możesz normalnie założyć, że może on odczytać dane wyjściowe z dowolnego programu, który wysyła do STDOUT, a zatem możesz dostosować go do własnych potrzeb i uzyskać przewidywalne wyniki.Podkreśla, że program nie zawiedzie, jeśli STDIN nie jest plikiem.
Nie jest bezpiecznie założyć, że jeśli
program1 < foo
prace następniecat foo | program1
będzie również pracować. Jednak można bezpiecznie założyć coś przeciwnego. Ten program działa, jeśli STDIN jest plikiem, ale kończy się niepowodzeniem, jeśli wejście jest potokiem, ponieważ używa funkcji seek:Koszt wydajności
Dodatkowa opłata jest płatna
cat
. Aby dać wyobrażenie o tym, ile przeprowadziłem kilka testów, aby zasymulować linię bazową (cat
), niską przepustowość (bzip2
), średnią przepustowość (gzip
) i wysoką przepustowość (grep
).Testy zostały przeprowadzone na low-endowym systemie (0,6 GHz) i zwykłym laptopie (2,2 GHz). Przeprowadzono je 10 razy w każdym systemie i wybrano najlepszy czas, aby naśladować optymalną sytuację dla każdego testu. ISO ISO to ubuntu-11.04-desktop-i386.iso. (Ładniejsze tabele tutaj: http://oletange.blogspot.com/2013/10/useless-use-of-cat.html )
Wyniki pokazują, że przy małej i średniej przepustowości koszt jest rzędu 1%. Jest to dobrze mieszczące się w zakresie niepewności pomiarów, więc w praktyce nie ma różnicy.
W przypadku dużej przepustowości różnica jest większa i istnieje wyraźna różnica między nimi.
Prowadzi to do wniosku:
<
zamiastcat |
if:W przeciwnym razie nie ma znaczenia, czy używasz,
<
czycat |
.Dlatego też powinieneś przyznać nagrodę UUoC tylko wtedy, gdy:
źródło
Myślę, że (w tradycyjny sposób) użycie potoku jest nieco szybsze; na moim pudełku użyłem
strace
polecenia, aby zobaczyć, co się dzieje:Bez rury:
I z rurą:
Możesz wykonać trochę testów
strace
itime
polecenia z coraz dłuższymi poleceniami, aby uzyskać dobre testy porównawcze.źródło
strace
pokazuje, że jest szybsze -strace
nie śledziwc -l
wykonania w drugim przypadku. Tutaj śledzi tylko pierwsze polecenie rurociągu.strace -f sh -c 'wc -l < wrong_output.c'
obokstrace -f sh -c 'cat wrong_output.c | wc -l'
.cat
: ideone.com/2w1W42#stderrmkfifo
tworzy nazwaną potokę . Anonimowa rura jest konfigurowana za pomocąpipe(2)
rozwidlenia, a następnie rozwidlenia, a rodzic i dziecko zamykają różne końce rury. Ale tak, ta odpowiedź jest totalnie nonsensowna i nawet nie próbowałem liczyć wywołań systemowych ani używaćstrace -O
do mierzenia narzutów, ani-r
oznaczać czasu każdego połączenia w odniesieniu do ostatniego ...