12

print message not shown in nohup.out?

 4 years ago
source link: https://jdhao.github.io/2021/03/16/std_stream_buffering_in_python/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

print message not shown in nohup.out?

2021-03-16590 words 3 mins read 47 times read

When starting a long-running Python program, I often run it under nohup so I can redirect all the output to nohup.out for easier inspection. I use nohup python test.py& to run the process in the background. Then I can use tail -f nohup.out to monitor the output from this program.

One strange issue I met is that all messages from the print() function are missing. To reproduce this issue, run the following test.py with command nohup python test.py&:

import time

n = 20
for i in range(n):
    time.sleep(0.5)
    print(f"this is loop {i}")

Then use tail -f nohup.out to monitor the output. Notice that there is no output for some time. Then, all of a sudden, all the output is printed.

However, if we directly run this program (python test.py), to our expectations, the messages are shown one at a time.

Buffering behavior of sys.stdout and sys.stderr

This has something to do with the stream buffering behavior of Python. The print() function in Python will print message to the sys.stdout stream. When we print directly to the console, in this case, the stdout stream is used interactively, it will be line-buffered, i.e., the message will be shown in the terminal once a new line is met.

If we use nohup, stdout is redirected to a file (nohup.out), it will be block-buffered in this case, i.e., only when the size of the output reaches a certain limit, will they be put into the destination (nohup.out file). So we can not see each print message in a timely manner. When the program stops, all the output is flushed to nohup.out, that is when we see those messages.

This behavior of sys.stdout and sys.stderr is documented here:

When interactive, stdout and stderr streams are line-buffered. Otherwise, they are block-buffered like regular text files.

This explains why the messages is not shown promptly if we redirect stdout to nohup.out, since stdout is block buffered in this case. If we use sufficiently large message, it will also be shown immediately since the output buffer is full.

To verify this, we modify test.py a little bit:

import time

n = 20
for i in range(n):
    time.sleep(0.5)
    print(f"{i}" + "a" * 8192)

Run it using nohup and check the output, you will find that the messages are indeed printed separately, since each message is now big enough (more than 8192 bytes).

For stderr, users may want to see the error messages immediately when they are produced even if it is redirected. In Python 3.9, the behavior of stderr is changed. The new doc is:

When interactive, the stdout stream is line-buffered. Otherwise, it is block-buffered like regular text files. The stderr stream is line-buffered in both cases.

Thus, after Python 3.9, stderr will always be line-buffered, whether the error message is displayed on the terminal or redirected to a file.

Show the message without buffering

To show the printed message immediately, we may run Python in unbuffered mode with the -u flag:

-u : force the stdout and stderr streams to be unbuffered

nohup python -u test.py

Another way is to add flush=True to print() function so that output will be flushed to its destination forcibly.

print(f"this is loop {i}", flush=True)

References

Author jdhao

LastMod 2021-03-17

License CC BY-NC-ND 4.0

Reward
Why is Wrong Stacktrace Printed for My Code?

Recommend

  • 32
    • 微信 mp.weixin.qq.com 5 years ago
    • Cache

    nohup VS screen

    说到在Linux系统上后台运行任务,可能很多人的第一反应是 nohup 命令,可能还会有人提到 screen 命令。今天老张就给大家介绍这两个命...

  • 5
    • arminli.com 4 years ago
    • Cache

    Linux中的nohup与2>&1 &

    Armin's BlogLinux中的nohup与2>&1 &November 11, 2016nohup 是 Linux 的一个常用命令,当你想要在退出账户或者关闭终端后进程仍在运行时,就可以使用 nohup 命令。nohup 就是不挂断的意思(no...

  • 9
    • www.lujun9972.win 3 years ago
    • Cache

    nohup,setsid与disown的不同之处

    nohup,setsid与disown的不同之处 nohup,setsid与disown都可以用来让需要长期运行的程序在退出终端后继续在后台运行。 然而它们实现这一目的的原理不同,因此使用起来也有一些不同。 退出终端时发生了什么 让我们先看...

  • 4

    SIGHUP, nohup, disown 以及 expect + sudo + bash + ssh 本文来自

  • 3
    • viencoding.com 3 years ago
    • Cache

    Linux后台运行进程nohup

    Linux 后台运行 我们常常会用终端连接Linux服务器,然后在运行类似Tomcat 、Web Logic等 web容器的时候希望退出终端依然可以运行。 我们可以通过 nohup command & 来使程序后台运 以Tomcat为例

  • 6

    ssh升级后nohup进程在终端退出后消失, ssh版本如下: # ssh -VOpenSSH_8.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017 怀疑是OpenSSH的bug。 临时解决办法终端ssh登录后,再通过:su - 用户...

  • 2

    V2EX  ›  Windows Windows 下对应 nohup &的命令是什么?   dcsuibian · 7 小时 24 分钟...

  • 7

    nohup: redirecting stderr to stdout解决办法

  • 5
    • xugaoxiang.com 2 years ago
    • Cache

    Linux常用命令-54:nohup

    迷途小书童的Note nohup 命令可以将程序以忽略挂起信号的方式运行起来,程序的输出信息将不会显...

  • 9
    • xv44586.github.io 2 years ago
    • Cache

    nohup踩坑记

    最近在测试horovod下...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK