2010-03-31 21 views
13

Czy istnieje przypadek ... lub kontekst, w którym cat file | ... zachowuje się inaczej niż ... <file?plik cat | ... vs ... <plik

+0

Jeśli pytasz, dlaczego widzisz jedną formę lub inną, używaną w różnych miejscach, wydaje się to być kwestią osobistych preferencji. Kernighan i Pike zauważyli to w 1984 roku: http://www.amazon.com/Unix-Programming-Environment-Prentice-Hall-Software/dp/013937681X – msw

+1

Należy do superuser.com –

Odpowiedz

9

Podczas odczytu ze zwykłego pliku, cat jest odpowiedzialny za odczyt danych, wykonuje je zgodnie z oczekiwaniami i może ograniczać je w sposobie, w jaki zapisuje je do potoku. Oczywiście same treści są zachowane, ale wszystko inne może zostać skażone. Na przykład: wielkość bloku i czas nadejścia danych. Dodatkowo rura sama w sobie nie zawsze jest neutralna: służy jako dodatkowy bufor między wejściem a wejściem.

Szybki i łatwy sposób, aby rozmiar bloku pozorny problem:

$ cat large-file | pv >/dev/null 
5,44GB 0:00:14 [ 393MB/s] [    <=>         ] 
$ pv <large-file >/dev/null 
5,44GB 0:00:03 [1,72GB/s] [=================================>] 100% 
+1

Ciekawe, chociaż biorąc pod uwagę, że read() używa skończony bufor, tak czy inaczej trafisz w niektóre procesy minimalny rozmiar bufora. Strace pokazuje, że kot używa 32kB czyta i pv 128kB na mojej platformie. – msw

+0

O, hej, mój przykład nie pasuje właściwie do pytania, ponieważ nie używam

+0

@msw dostanie * bardzo * w zależności od implementacji 'cat', ale postaram się uczynić to widocznym w inny sposób. –

1

cat file | uruchamia inny program (cat), który nie musi rozpoczynać się w drugim przypadku. Powoduje to także większe zamieszanie, jeśli chcesz użyć "tutaj dokumentów". Ale powinno zachowywać się tak samo.

4

cat pozwoli Ci potokować wiele plików sekwencyjnie. W przeciwnym razie przekierowanie < i cat file | powoduje takie same efekty uboczne.

2

Rury spowodować powłoki w tle powoływać się na komendzie po prawej stronie. Wpływa to na zmienne środowiskowe.

cat foo | while read line 
do 
    ... 
done 
echo "$line" 

kontra

while read line 
do 
    ... 
done < foo 
echo "$line" 
+0

Obie dały takie same wyniki, gdy je wypróbowałem. –

+0

interesujący efekt uboczny. – pra

+0

@JB: Ustaw zmienną w pętli, a następnie echo po pętli. Zmieniona wartość będzie obowiązywała tylko po przekierowanym formularzu i nie będzie po wypisanym formularzu. Kolejną demonstracją jest "cd" wewnątrz pętli i 'pwd' po pętli. –

4

oprócz rzeczy zamieszczonych przez innych użytkowników, przy użyciu przekierowanie wejściowe z pliku, standardowe wejście jest plik ale gdy potokiem wyjście kota na wejście, standardowe wejście jest strumień z zawartością pliku. Kiedy standardowe wejście to plik będzie mógł szukać w pliku, ale potok nie pozwoli na to. Widać to poprzez znalezienie pliku zip i uruchamiając następujące polecenia:

zipinfo /dev/stdin < thezipfile.zip 

i

cat thezipfile.zip | zipinfo /dev/stdin 

Pierwsze polecenie pokaże zawartość na kartę SD, podczas gdy drugi pokaże błąd, choć jest błędem wprowadzającym w błąd, ponieważ zipinfo nie sprawdza później wyniku wyszukiwania i błędów.

3

A bezużyteczne użycie kota to zawsze należy go unikać:. To jest jak jazda z hamulca ręcznego na. To marnuje cykle procesora na nic, system operacyjny nieustannie przełącza kontekst między procesem kotów a następnym w rurze. Gdyby wszystkie bezużyteczne koty na świecie zniknęły i przestałyby być wymyślane, wymyślane na nowo, przekazywane z ojca na syna, nie mielibyśmy globalnego ocieplenia, ponieważ moglibyśmy z łatwością żyć z 1,21 Gigawatów zaoszczędzonej energii.

Dzięki. Czuję się teraz lepiej. Dołączcie do mnie w mojej krucjacie, aby zniweczyć bezużyteczne wykorzystanie kota na stackoverflow. Ta strona jest, o ile ją postrzegam, dużym wkładem w rozprzestrzenianie się bezużytecznych kotów. Nie obwiniam początkujących, ale chcę ich uczyć. Pracownicy i nowicjusze świata, poluzuj hamulce ręczne i ocal planetę !!! 1!

1

Jeszcze jedna różnica polega na zachowaniu na blokującym pliku wejściowym open().

Na przykład, zakładając wejście jest FIFO bez pisarzy, jedno wezwanie nie będzie tarło żadnych programów dziecięcych aż plik wejściowy jest otwarty, a drugi będzie tarło dwa procesy:

prog ... < a_fifo  # 'prog' not launched until shell can open file 
cat a_fifo | prog ... # 'prog' and 'cat' are running (latter may block on open) 

W praktyce rzadko sprawy, z wyjątkiem przypadków wymyślonych. prog może okresowo rejestrować lub wykonywać pewne prace czyszczące w oczekiwaniu na dane wejściowe, na przykład, co może się zdarzyć, nawet jeśli żadne dane wejściowe nie są dostępne. (Dlaczego nie miałby być wystarczająco zaawansowany, aby otworzyć własne wejście bez blokowania?)

Powiązane problemy