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?

James Dean
źródło
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
2
więcej zadane pytanie unix.stackexchange.com/questions/25372
Trevor Boyd Smith

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
Eduardo Ivanec
źródło
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
topielnik
źródło
-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.

Calmarius
źródło
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.

Steve HHH
źródło
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.

Chris S.
źródło
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.

Paweł Brodacki
źródło
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.

wolfgangsz
źródło
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.

Benj
źródło
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