Nohup no está escribiendo el registro en el archivo de salida

141

Estoy usando el siguiente comando para ejecutar un script de Python en segundo plano:

nohup ./cmd.py > cmd.log &

Pero parece que nohup no está escribiendo nada en el archivo de registro. cmd.log se crea pero siempre está vacío. En el script de Python, estoy usando en sys.stdout.writelugar de printimprimir en la salida estándar. ¿Estoy haciendo algo mal?


fuente
¿Qué variante de nohupestás usando? La versión BSD escribe en un archivo llamado nohup.outen el directorio actual (o $HOME/nohup.outsi el directorio actual no se puede escribir). No veo una manera de cambiar el nombre del archivo de salida ...
Wulong
@wulong Eso es solo si stdout es una terminal.
John Kugelman
También probé el comando sin redireccionamiento y no creó el archivo nohup.out en absoluto. No sé qué variante es, pero estoy en SunOS 5.10 si eso ayuda.

Respuestas:

103

Parece que necesita enjuagar stdout periódicamente (por ejemplo sys.stdout.flush()). En mis pruebas, Python no hace esto automáticamente incluso printhasta que se cierra el programa.

wulong
fuente
17
Python, así como otros programas basados ​​en C stdio, utilizan el almacenamiento en línea en el caso interactivo (stdout está conectado a un tty) y el almacenamiento en bloque cuando se redirige a un archivo. Si python -uno funciona; nohuppodría haber introducido su propio almacenamiento en búfer.
jfs
12
@JFSebastian A partir de hoy, nohupno amortigua la salida y python -ufunciona bien. (solo una actualización para personas)
Pijusn
1
@Pius: nohupes una utilidad POSIX, podría haber diferentes implementaciones en diferentes plataformas. Por cierto, python3 I / O ya no está basado en C stdio, pero tiene un comportamiento de almacenamiento en búfer similar.
jfs
381

Puede ejecutar Python con el -uindicador para evitar el almacenamiento en búfer de salida:

nohup python -u ./cmd.py > cmd.log &
vz0
fuente
12
¡Esto es mejor! Muchas gracias :)
Sadjad
@kommradHomer Supongo que depende de la cantidad de salida en stdout / stderr que produce su programa.
vz0
1
Funciona de maravilla. También creo que es una mejor respuesta que la seleccionada como correcta. ¿Podría marcar esto como correcto para no confundir a los demás?
Ondrej Burkert
1
Advertencia: no siempre funciona . No se porque. ¿Vos si?
Basj
3
esta debería ser la respuesta aceptada ... hice lo que quería. ¡Gracias!
krinker
42
  • Usando -u con nohuptrabajado para mí. Usando -uobligará al stdout, stderrarroyos ser sin búfer. No afectará a stdin. Todo se guardará en el archivo " nohup.out ". Me gusta esto-

    nohup python -u your_code.py &

    También puede guardarlo en su directorio. De esta manera-

    nohup python -u your_code.py > your_directory/nohup.out &
  • Además, puedes usar PYTHONUNBUFFERED. Si lo configura en una cadena no vacía, funcionará igual que la -uopción. Para usar esto, ejecute los siguientes comandos antes de ejecutar el código python.

    export PYTHONUNBUFFERED=1

    o

    export PYTHONUNBUFFERED=TRUE

PD : sugeriré usar herramientas como cron-job para ejecutar cosas en segundo plano y la ejecución programada.

Nurul Akter Towhid
fuente
¿Cuál es la diferencia con la respuesta de @ vz0?
Deqing
1
@Deqing no hay diferencia.
Overcode el
2

Python 3.3 y superior tiene un argumento de descarga para imprimir y este es el único método que funcionó para mí.

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

Tuve un problema similar, pero no estaba conectado con un proceso de Python. Estaba ejecutando un script que hacía un nohup y el script se ejecutaba periódicamente a través de cron.

Pude resolver el problema:

  1. redirigiendo el stdin, stdout y stderr
  2. asegurando que el script que se invoca a través de nohup no ejecuta nada más en segundo plano

PD: mis scripts fueron escritos en ksh ejecutándose en RHEL

Pradeep Anchan
fuente