Mam długo działający skrypt Pythona, który okresowo wysyła dane do standardowego wyjścia, które wywołałem za pomocą czegoś takiego:
python script.py > output.txt
Ten skrypt działa już od jakiegoś czasu i chcę go zatrzymać za pomocą Ctrl+, Cale nie stracę żadnego z jego wyników. Niestety, kiedy zaimplementowałem skrypt, zapomniałem opróżnić bufor po każdej linii danych wyjściowych czymś takim sys.stdout.flush()
( poprzednio sugerowane rozwiązanie wymuszające opróżnianie danych wyjściowych), więc wywołanie Ctrl+ w Ctej chwili spowoduje, że stracę całą moją wydajność.
Jeśli zastanawiasz się, czy jest jakiś sposób interakcji z działającym skryptem Pythona (lub, bardziej ogólnie, działającym procesem), aby zmusić go do opróżnienia bufora wyjściowego. Nie pytam, jak edytować i ponownie uruchamiać skrypt, aby poprawnie się opróżnił - to pytanie dotyczy konkretnie interakcji z uruchomionym procesem (i, w moim przypadku, utraty danych wyjściowych z mojego bieżącego wykonania kodu).
fileobject.c
) niż 2.7 . Ktoś musi zagłębić się wio
moduł.Nie ma rozwiązania twojego bezpośredniego problemu. Jeśli skrypt już się rozpoczął, nie można zmienić trybu buforowania po fakcie. Są to wszystkie bufory pamięci i wszystko to jest konfigurowane po uruchomieniu skryptu, otwieraniu uchwytów plików, tworzeniu potoków itp.
Długie podejście, jeśli i tylko jeśli część lub całość buforowania jest wykonywana na poziomie IO na wyjściu, możesz wykonać
sync
polecenie; ale w takich przypadkach jest to na ogół mało prawdopodobne.W przyszłości możesz użyć
-u
opcji Pythona * do uruchomienia skryptu. Zasadniczo wiele poleceń ma opcje specyficzne dla polecenia, aby wyłączyć buforowanie stdin / stdout, a także może być ogólny sukces zunbuffer
poleceniem zexpect
pakietu.A Ctrl+ Cspowodowałoby opróżnienie buforów na poziomie systemu, gdy program zostanie przerwany, chyba że buforowanie jest wykonywane przez sam Python i nie zaimplementował logiki opróżniania własnych buforów za pomocą Ctrl+ C. Zawieszenie, awaria lub zabicie nie byłyby tak miłe.
* Zmusza stdin, stdout i stderr do całkowitego niebuforowania.
źródło
Dokumentacja Pythona 2.7.7, sekcja „Konfiguracja i użytkowanie Pythona”, podsekcja 1. Wiersz poleceń i środowisko , opisuje ten argument Pythona:
A także ta zmienna środowiskowa:
źródło
sys.stdout.flush()
, ale twoja-u
opcja wydaje się jeszcze łatwiejsza), ale właśnie zapomniałem to zrobić, wywołując mój kod. Mając już uruchomiony kod przez ponad tydzień, miałem nadzieję, że istnieje sposób na uzyskanie moich danych wyjściowych bez konieczności ponownego uruchamiania kodu przez kolejny tydzień.Wygląda na to, że byłem zbyt ostrożny w przegrywaniu przez buforowane wyjście po uruchomieniu Ctrl-C; zgodnie z tym postem powinienem oczekiwać, że bufor zostanie opróżniony, jeśli mój program ma normalne wyjście, co miałoby miejsce, gdybym nacisnął Ctrl-C. Z drugiej strony straciłbym buforowane wyjście, gdybym zabił skrypt za pomocą SIGKILL lub podobnego.
źródło
Myślę, że innym możliwym rozwiązaniem może być wymuszenie zabicia procesu z zrzutem rdzenia, a następnie analiza zawartości pamięci pośmiertnie.
źródło