Nohup nie zapisuje dziennika do pliku wyjściowego


141

Używam następującego polecenia, aby uruchomić skrypt Pythona w tle:

nohup ./cmd.py > cmd.log &

Wygląda jednak na to, że nohup nic nie zapisuje do pliku dziennika. cmd.log jest tworzony, ale zawsze jest pusty. W skrypcie Pythona używam sys.stdout.writezamiast printdrukowania na standardowe wyjście. Czy robię coś złego?


nohupZ jakiego wariantu korzystasz? Wersja BSD zapisuje do pliku wywołanego nohup.outw bieżącym katalogu (lub $HOME/nohup.outjeśli bieżący katalog nie jest zapisywalny). Nie widzę sposobu na zmianę nazwy pliku wyjściowego ...
wulong

@wulong Dzieje się tak tylko wtedy, gdy stdout jest terminalem.
John Kugelman,

Wypróbowałem również polecenie bez przekierowania i w ogóle nie utworzyło pliku nohup.out. Nie wiem, który to wariant, ale korzystam z SunOS 5.10, jeśli to pomaga.

Odpowiedzi:


103

Wygląda na to, że musisz okresowo opróżniać stdout (np sys.stdout.flush().). W moich testach Python nie robi tego automatycznie, nawet printdopóki program nie zakończy działania.


17
Python, podobnie jak inne programy oparte na stdio C, używa buforowania linii w przypadku interaktywnym (stdout jest połączone z terminalem tty) i buforowania bloków po przekierowaniu do pliku. Jeśli python -unie działa; nohupmógł wprowadzić własne buforowanie.
jfs

12
@JFSebastian Od dzisiaj nohupnie buforuje wyjścia i python -udziała dobrze. (tylko aktualizacja dla ludzi)
Pijusn

1
@Pius: nohupto narzędzie POSIX, które może mieć różne implementacje na różnych platformach. btw, I / O python3 nie jest już oparte na C stdio, ale ma podobne zachowanie buforowania.
jfs

382

Możesz uruchomić Pythona z -uflagą, aby uniknąć buforowania wyjścia:

nohup python -u ./cmd.py > cmd.log &

12
To jest lepsze!
Wielkie

@kommradHomer Myślę, że to zależy od ilości danych wyjściowych na stdout / stderr, które produkuje twój program.
vz0

1
Działa jak marzenie. Myślę też, że jest to lepsza odpowiedź niż ta wybrana jako poprawna. Czy mógłbyś oznaczyć to jako poprawne, aby nie mylić innych?
Ondrej Burkert

1
Ostrzeżenie: to nie zawsze działa . Nie wiem dlaczego. Czy ty?
Basj

3
to powinna być akceptowana odpowiedź ... zrobiłem, co chciałem. dzięki!
krinker

42
  • Używanie -u z nohupzadziałało dla mnie. Korzystanie -uzmusi stdout, stderrstrumieni być buforowane. Nie wpłynie to na stdin. Wszystko zostanie zapisane w pliku „ nohup.out ”. Lubię to-

    nohup python -u your_code.py &

    Możesz również zapisać go w swoim katalogu. Tą drogą-

    nohup python -u your_code.py > your_directory/nohup.out &
  • Możesz także użyć PYTHONUNBUFFERED. Jeśli ustawisz go na niepusty ciąg, będzie działać tak samo, jak -uopcja. Aby użyć tego, uruchom poniższe polecenia przed uruchomieniem kodu Pythona.

    export PYTHONUNBUFFERED=1

    lub

    export PYTHONUNBUFFERED=TRUE

PS : Zasugeruję użycie narzędzi takich jak cron-job do uruchamiania rzeczy w tle i wykonywania zaplanowanych.


Jaka jest różnica w odpowiedzi z @ vz0?
Deqing

1
@Deqing nie ma różnicy.
Przekodowanie


2

Python 3.3 i nowsze wersje mają argument flush do wydrukowania i jest to jedyna metoda, która działała dla mnie.

print("number to train = " + str(num_train), flush=True)
print("Using {} evaluation batches".format(num_evals), flush=True)

0

Miałem podobny problem, ale nie był związany z procesem w Pythonie. Uruchomiłem skrypt, który wykonał nohup, a skrypt był uruchamiany okresowo przez cron.

Udało mi się rozwiązać problem poprzez:

  1. przekierowanie stdin, stdout i stderr
  2. upewnienie się, że skrypt wywoływany przez nohup nie uruchamia niczego innego w tle

PS: moje skrypty zostały napisane w ksh działającym na RHEL

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.