Nohup没有将日志写入输出文件

186

我正在使用以下命令在后台运行Python脚本:

nohup ./cmd.py > cmd.log &

但是似乎nohup没有将任何内容写入日志文件。cmd.log文件已创建,但始终为空。在Python脚本中,我使用sys.stdout.write而不是print将输出打印到标准输出。我做错了什么吗?


你使用的是哪个版本的 nohup?BSD 版本会将输出写入到当前目录下的一个名为 nohup.out 的文件中(如果当前目录不可写,则写入到 $HOME/nohup.out 文件中)。我没有看到可以更改输出文件名的方法... - wulong
@wulong 这只有在 stdout 是终端时才会发生。 - John Kugelman
我也尝试了不带重定向的命令,但它根本没有创建nohup.out文件。我不知道它是哪个变体,但如果有帮助的话,我在SunOS 5.10上。 - user1642513
7个回答

521

您可以使用-u标志运行Python以避免输出缓冲:

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

16
这样更好!非常感谢 :) - Sadjad
@kommradHomer 我想这取决于你的程序在标准输出/标准错误流上产生的输出量。 - vz0
1
运行得非常好。我认为这是比被选为正确答案的那个更好的答案。您能否将其标记为正确,以免混淆其他人? - Ondrej Burkert
1
警告:它并不总是有效(https://dev59.com/DJLea4cB1Zd3GeqP8_Ro)。我不知道为什么。你知道吗? - Basj
3
这应该是被接受的答案...符合我的要求。谢谢! - krinker
谢谢!!! 工作得很好。这是解决此问题的最佳答案。 - Sudhir Arya

115

看起来你需要定期刷新stdout(例如sys.stdout.flush())。在我的测试中,即使使用print,Python也不会自动执行此操作,直到程序退出。


22
Python以及其他基于C stdio的程序在交互模式下使用行缓冲(标准输出连接到tty),在重定向到文件时则使用块缓冲。如果python -u无法正常工作,那么nohup可能会引入自己的缓冲。 - jfs
17
截至今日,“nohup”不会缓冲输出,而“python -u”可以很好地工作。(这只是一个更新,供人们参考) - Pijusn
1
@Pius:nohup是POSIX实用程序,在不同平台上可能有不同的实现。另外,Python3的I/O不再基于C stdio,但具有类似的缓冲行为。 - jfs
@jfs stderr缓冲行为在Python 3.9中发生了变化,现在始终是行缓冲。请参见此处 - jdhao

77
  • 使用nohup-u一起使用对我有用。使用-u将强制stdoutstderr流无缓冲区。它不会影响标准输入。所有内容都将保存在 "nohup.out " 文件中。像这样-

nohup python -u your_code.py &
您还可以将其保存到您的目录中。这样-
nohup python -u your_code.py > your_directory/nohup.out &
  • 此外,您可以使用PYTHONUNBUFFERED。 如果将其设置为非空字符串,则与-u选项相同。 要使用它,请在运行Python代码之前运行以下命令。

  • export PYTHONUNBUFFERED=1
    
    或者
    export PYTHONUNBUFFERED=TRUE
    

    P.S.- 我建议使用cron-job这样的工具在后台运行和定期执行任务。


    2
    @vz0的答案有什么不同? - Deqing
    1
    @Deqing 没有任何区别。 - Overcode

    21

    5

    Python 3.3及以上版本的print函数有一个flush参数,这是我使用过唯一可行的方法。

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

    0

    我遇到了类似的问题,但与Python进程无关。我正在运行一个脚本,该脚本通过cron定期运行,并执行nohup。

    我通过以下方式解决了这个问题:

    1. 重定向stdin、stdout和stderr
    2. 确保通过nohup调用的脚本没有在后台运行其他任何东西

    PS:我的脚本是在RHEL上运行的ksh编写的。


    -1

    我以以下方式运行我的脚本,一点问题都没有:

    nohup python my_script.py &> my_script.out &
    

    根据您的语法,看起来您只是在输入后面缺少了一个"&"符号...


    你是如何找到这个解决方法的? - Abhishek Jain
    你是怎么找到这个解决办法的? - Abhishek Jain

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接