ciągły odczyt z nazwanej rury (cat lub tail -f)


16

Skonfigurowałem rsyslogrejestrowanie niektórych zdarzeń dziennika w /dev/xconsole:

*.*;cron.!=info;mail.!=info      |/dev/xconsole

/dev/xconsoleto nazwany potok ( fifo). Jeśli chcę zobaczyć, co jest rejestrowane, mogę to zrobić cat /dev/xconsole. Jestem zaskoczony, widząc, że polecenie cat /dev/xconsolenie kończy się po odczytaniu pliku, ale działa jak tail -f. innymi słowy, oba polecenia zachowują się tak samo:

cat /dev/xconsole
tail -f /dev/xconsole

Czy ktoś może wyjaśnić, dlaczego tak jest?

Czy jest jakaś różnica między nimi?

Odpowiedzi:


18

catkontynuuje czytanie, dopóki nie otrzyma EOF. Rura wytwarza EOF na wyjściu tylko wtedy, gdy otrzymuje EOF na wejściu. Demon rejestrujący otwiera plik, zapisuje do niego i utrzymuje go otwarty - podobnie jak w przypadku zwykłego pliku - aby EOF nigdy nie był generowany na wyjściu. catpo prostu kontynuuje czytanie, blokując za każdym razem, gdy wyczerpuje to, co aktualnie znajduje się w potoku.

Możesz to wypróbować ręcznie:

$ mkfifo test
$ cat test

I w innym terminalu:

$ cat > test
hello

Wyjdzie na drugim terminalu. Następnie:

world

Na drugim terminalu będzie więcej danych wyjściowych. Jeśli teraz Ctrl-D wejście, to drugie catrównież się zakończy.

W takim przypadku jedyną zauważalną różnicą między cati tail -fbędzie, jeśli demon rejestrujący zostanie zakończony lub zrestartowany: catzatrzyma się na stałe, gdy koniec zapisu potoku zostanie zamknięty, ale tail -fbędzie kontynuował (ponownie otwierał plik), gdy demon zostanie zrestartowany.


przepraszam, nie widzę skąd wziąłby się „świat” w twoim przykładzie :)
Alexander Mills

Po wpisaniu.
Michael Homer,

1
A potem piszesz world, a oto „świat” pojawia się w drugim terminalu.
Michael Homer,

2

Istnieje również różnica w buforowaniu między cati tail -f. Możesz to sprawdzić:

Utwórz potok: mkfifo pipe

Rozpocznij czytanie potoku, używając catw tle:cat pipe &

Otwórz potok i pisz do niego co sekundę: perl -MFcntl -we 'sysopen(my $fh, "pipe", O_WRONLY | O_NONBLOCK); while() {warn "written: " . syswrite($fh, "hello\n"); sleep 1}'

Teraz spróbuj tego z tail -f pipe &zamiast cat. Możesz więc zobaczyć, że catdrukuje linie, jak tylko zostaną zapisane do potoku za pomocą skryptu perl, a tail -f buforuje je do 4 KB przed drukowaniem na standardowe wyjście.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.