Czy istnieje sposób przekierowania wyjścia do pliku bez buforowania w systemach unix / linux?


49

Mam długo działający proces wsadowy, który wyprowadza niektóre informacje debugowania i procesu na standardowe wyjście. Jeśli po prostu uruchomię z terminala, mogę śledzić „gdzie to jest”, ale wtedy dane stają się zbyt duże i przewijają się poza ekran.

Jeśli przekieruję na wyjście do pliku „> out.txt”, w końcu otrzymam całe wyjście, ale jest ono buforowane, więc nie mogę już zobaczyć, co robi teraz.

Czy istnieje sposób na przekierowanie wyjścia, ale nie buforowanie zapisów?


1
Czy mógłbyś rzucić okiem na moją „debatę” (i @cnst) poniżej, zgaduję, że jedyne, czego chcesz, to zobaczyć wynik w tym samym czasie, co zalogowanie go do pliku. Jeśli znalazłeś rozwiązanie, daj nam znać;)!
Benj

Odpowiedzi:


52

Możesz jawnie ustawić opcje buforowania standardowych strumieni za pomocą setvbufwywołania w C (patrz ten link ), ale jeśli próbujesz zmodyfikować zachowanie istniejącego programu, spróbuj stdbuf(część coreutilszaczynająca się od wersji 7.5 najwyraźniej).

Buforuje stdoutdo linii:

stdbuf -oL command > output

To stdoutcałkowicie wyłącza buforowanie:

stdbuf -o0 command > output

aaarghhh ... Moje Ubuntu ma tylko 7,4 coreutils ... :(
Calmarius

@Calmarius: kompilacja coreutils powinna być dość łatwa. Po prostu pobierz nową wersję z ftp.gnu.org/gnu/coreutils i wypróbuj . To standardowa ./configure && makeopłata. Nie musisz nawet go później instalować, możesz po prostu użyć stdbufpliku binarnego src/.
Eduardo Ivanec

podwójne argh. Potrzebuję tego na starej dystrybucji Centos ORAZ OSX, a także Ubuntu.
edk750

więcej pozytywnych odpowiedzi unix.stackexchange.com/a/25378/5510
Trevor Boyd Smith

Czy jest sposób na wymuszenie zewnętrznych buforów potoku / printf dla już uruchomionego procesu ze znanym PID?
Mvorisek

9

Możesz uzyskać wyjście buforowane wierszem do pliku, używając scriptpolecenia w następujący sposób:

stty -echo -onlcr   # avoid added \r in output
script -q /dev/null batch_process | tee output.log        # Mac OS X, FreeBSD
script -q -c "batch_process" /dev/null | tee output.log   # Linux
stty echo onlcr

-1, ponieważ: a) w przeciwieństwie do zaakceptowanej odpowiedzi, to nie działa, jeśli chcesz uruchomić polecenie w tle (polecenie natychmiast kończy się bez zakończenia, batch_processjeśli dołączysz &do powyższego polecenia, przynajmniej na moim Linux-ie), co wydaje się jak niezwykle powszechny przypadek użycia, i b) nie ma tutaj wyjaśnienia, jak działa ta inkantacja.
Mark Amery

8

Na Ubuntu, pakiet unbufferprogramu (z expect-dev) wykonał dla mnie lewę. Po prostu biegnij:

unbuffer your_command

i to go nie buforuje.


6

Najłatwiejsze rozwiązanie, które znalazłem (nie wymagało instalowania żadnych pakietów stron trzecich) zostało wspomniane w podobnym wątku na stronie Unix i Linux : użyj scriptpolecenia. Jest stary i prawdopodobnie już zainstalowany.

$ script -q /dev/null long_running_command | print_progress       # FreeBSD, Mac OS X
$ script -q -c "long_running_command" /dev/null | print_progress  # Linux

Zauważ, że pierwszym parametrem nazwy pliku dla scriptpolecenia jest plik dziennika, który ma zostać zapisany . Jeśli po prostu uruchomisz script -q your_command, zastąpisz polecenie, które chcesz uruchomić, z plikiem dziennika. Sprawdź man script, aby być bezpiecznym, zanim spróbujesz.


4

wypróbuj scriptpolecenie; jeśli twój system go ma, przyjmuje nazwę pliku jako argument, cały tekst zrzucony na standardowe wyjście zostaje skopiowany do pliku. Jest to bardzo przydatne, gdy program instalacyjny wymaga interakcji.


Znam sztuczkę „script -a out.txt”. Zastanawiałem się, czy jest jakiś inny sposób, aby proces pisania nie buforował.
James Dean

3

Osobiście wolę przesyłanie danych wyjściowych polecenia, które chcę sprawdzić tee.

scriptzapisuje zbyt wiele informacji, w tym czas naciśnięć klawiszy i wiele znaków, które nie mogą zostać wydrukowane. To, co teeoszczędza, jest dla mnie o wiele bardziej czytelne dla człowieka.


Dodałbym również „| mniej” do wiersza poleceń.
HUB

4
Jestem pewien, że teewpływa na to również buforowanie. Często nadal wyświetlam częściowe linie wyświetlane przez tee podczas dzielenia wyjścia z findpoleceń.
Magellan

2

Przekieruj dane wyjściowe do pliku i postępuj zgodnie z tail -fpoleceniem.

Edytować

Jeśli nadal występuje problem z buforowaniem, skorzystaj z narzędzia syslog (które zasadniczo nie jest buforowane). Jeśli proces wsadowy działa jako skrypt powłoki, można to zrobić za pomocą polecenia logger. Jeśli zadanie wsadowe działa w języku skryptowym, i tak powinna istnieć możliwość logowania.


3
Właśnie to robię teraz, ale proces buforuje zapis do pliku i właśnie tego chcę uniknąć.
James Dean

Zobacz moją edycję, aby uzyskać zaktualizowaną propozycję.
wolfgangsz

1
To nie działa z oczywistych powodów. Kto do diabła rozdaje This answer is usefulodpowiedzi, które nie działają i nie mogą działać?
cnst

1

Możesz użyć teepolecenia, po prostu magia!

someCommand | tee logFile.logbędzie zarówno wyświetlacz w konsoli i zapisywać do pliku dziennika.


Nie działa teenie zatrzyma buforowania.
cnst

1
@ cnst Skutecznie, teenie uniknie buforowania, ale pozwoli ci tylko spojrzeć na wynik. Tego właśnie chciał @JamesDean (jak nie rozumiem jego pytania), ale myślę, że buforowanie nie jest tutaj tak naprawdę problemem. Jeśli masz więcej szczegółów, daj mi znać.
Benj

Chciał zobaczyć dane wyjściowe, a on nie otrzymuje żadnych danych wyjściowych (w niebuforowany sposób), a jednak sugerujesz skorzystanie z niego, teeaby uzyskać lepszy widok danych wyjściowych, których nie otrzymujesz?
cnst

1
Jak zrobiłem czerwone pytanie @JamesDean: „Przekierowuję dane wyjściowe do pliku„> out.txt ”” oznacza dla mnie brak danych wyjściowych konsoli, poczekaj na zakończenie procesu, dopóki całe dane wyjściowe zostaną przekierowane. Podczas używania >nic nie widać na konsoli. Wydaje mi się, że @JamesDean używa słowa „buforowanie”, aby to opisać. Zamieszczę komentarz na jego pytanie, aby mógł powiedzieć więcej o tym, czego chce.
Benj
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.