Nohup não está gravando log no arquivo de saída

141

Estou usando o seguinte comando para executar um script python em segundo plano:

nohup ./cmd.py > cmd.log &

Mas parece que o nohup não está gravando nada no arquivo de log. O cmd.log é criado, mas está sempre vazio. No script python, estou usando em sys.stdout.writevez de printimprimir na saída padrão. Estou fazendo algo errado?


fonte
Qual variante nohupvocê está usando? A versão do BSD grava em um arquivo chamado nohup.outno diretório atual (ou $HOME/nohup.outse o diretório atual não for gravável). Eu não vejo uma maneira de mudar o nome do arquivo de saída ...
Wulong
@ wulong Isso é apenas se stdout for um terminal.
John Kugelman
Também tentei o comando sem redirecionar e ele não criou o arquivo nohup.out. Não sei qual é a variante, mas estou no SunOS 5.10 se isso ajudar.

Respostas:

103

Parece que você precisa liberar o stdout periodicamente (por exemplo sys.stdout.flush()). Nos meus testes, o Python não faz isso automaticamente, mesmo printaté a saída do programa.

wulong
fonte
17
O python e outros programas baseados em C stdio usam buffer de linha em caso interativo (stdout está conectado a um tty) e buffer de bloco quando redirecionado para um arquivo. Se python -unão funcionar; nohuppode ter introduzido seu próprio buffer.
JFS
12
@JFSebastian A partir de hoje, nohupnão faz buffer de saída e python -ufunciona muito bem. (apenas uma atualização para as pessoas)
Pijusn
1
@Pius: nohupé um utilitário POSIX , pode haver implementações diferentes em plataformas diferentes. btw, a E / S python3 não é mais baseada em C stdio, mas possui um comportamento de buffer semelhante.
JFS
381

Você pode executar o Python com o -usinalizador para evitar o buffer de saída:

nohup python -u ./cmd.py > cmd.log &
vz0
fonte
12
Isto é melhor! Muito obrigado :)
Sadjad
@kommradHomer Acho que depende da quantidade de saída no stdout / stderr que o seu programa produz.
vz0
1
Funciona como um encanto. Eu também acho que é uma resposta melhor do que a selecionada como correta. Você poderia marcar isso como correto para não confundir os outros?
Ondrej Burkert
1
Aviso: nem sempre funciona . Não sei porque. Você?
Basj
3
esta deve ser a resposta aceita ... fiz o que eu queria. obrigado!
krinker
42
  • Usar -u com nohupfuncionou para mim. Usando -uforçará o stdout, stderrcórregos ser unbuffered. Não afetará o stdin. Tudo será salvo no arquivo " nohup.out ". Como isso-

    nohup python -u your_code.py &

    Você também pode salvá-lo em seu diretório. Deste jeito-

    nohup python -u your_code.py > your_directory/nohup.out &
  • Além disso, você pode usar PYTHONUNBUFFERED. Se você configurá-lo como uma sequência não vazia, funcionará da mesma forma que a -uopção. Para usar esta execução abaixo dos comandos antes de executar o código python.

    export PYTHONUNBUFFERED=1

    ou

    export PYTHONUNBUFFERED=TRUE

PS : vou sugerir o uso de ferramentas como cron-job para executar coisas em segundo plano e execução agendada.

Nurul Akter Towhid
fonte
Qual é a diferença com a resposta de @ vz0?
Deqing
1
@ Deqing não há diferença.
Overcode
2

Python 3.3 e acima tem um argumento de descarga para imprimir e este é o único método que funcionou para mim.

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

Eu tive um problema semelhante, mas não conectado a um processo Python. Eu estava executando um script que fazia um nohup e o script era executado periodicamente via cron.

Consegui resolver o problema da seguinte maneira:

  1. redirecionando o stdin, stdout e stderr
  2. garantir que o script que está sendo chamado via nohup não execute mais nada em segundo plano

PS: meus scripts foram escritos em ksh rodando no RHEL

Pradeep Anchan
fonte