在 CentOS 上使用 nohup 运行程序时,日志突然停止写入是常见现象,通常不是 nohup 本身的问题,而是缓冲、重定向、进程状态或磁盘/权限等原因造成的。下面按最常见到最隐蔽的顺序说明。
很多程序(尤其是 Python、Java、C++)不会实时写文件,而是先写内存缓冲区。
例如:
nohup python app.py > app.log 2>&1 &
Python 默认:
✅ 解决:
nohup python -u app.py > app.log 2>&1 &
或
stdbuf -oL python app.py > app.log 2>&1 &
日志停止 ≠ 还在跑。
检查进程:
ps -ef | grep app.py
或
jobs -l
查看 nohup.out 是否有错误:
tail -n 50 nohup.out
CentOS 上磁盘满时:
检查:
df -h
df -i # inode 满也会写不进
如果你用了 logrotate 或手动:
rm app.log
mv app.log app.log.1
但进程仍持有旧文件描述符:
✅ 验证:
ls -l /proc/<pid>/fd
✅ 解决:
logrotate + copytruncate错误写法:
nohup python app.py &
→ 默认写 nohup.out
如果你在别的目录看 app.log,当然没内容。
✅ 推荐标准写法:
nohup python app.py > app.log 2>&1 &
虽然 nohup 本意是防 SIGHUP,但:
disown 不完整✅ 更稳方案:
setsid python app.py > app.log 2>&1 &
CentOS 默认开启 SELinux,可能禁止写某些目录。
检查:
getenforce
临时验证:
setenforce 0
mount | grep ro
# 1. 进程在不在
ps -ef | grep 程序名
# 2. 文件描述符
ls -l /proc/<pid>/fd
# 3. 磁盘
df -h
df -i
# 4. 日志最后内容
tail -n 100 app.log
# 5. 是否缓冲
python -u / stdbuf
setsid python -u app.py >> app.log 2>&1 < /dev/null &
或用 systemd(最稳妥):
[Service]
ExecStart=/usr/bin/python app.py
StandardOutput=append:/var/log/app.log
Restart=always
如果你愿意,可以把:
ps / tail 输出发出来,我可以帮你精确定位是哪一类问题。