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?


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

wulong
źródło
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 &
vz0
źródło
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.

Nurul Akter Towhid
źródło
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)
Ganesh Krishnan
źródło
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

Pradeep Anchan
źródło