ulimit -f 可直接限制单个文件最大大小,内核级拦截写入并返回efbig错误;支持临时设置(如ulimit -f 100m)和永久配置(limits.conf或systemd limitfsize),需配合logrotate等工具实现可靠日志管理。

用 ulimit -f 可以直接限制当前 shell 及其子进程能创建的单个文件最大大小,对防止日志无限写入非常有效——它不是监控或事后清理,而是在内核写入时就拦截超限操作,让 write() 系统调用直接返回 EFBIG 错误。
临时生效:快速验证和应急控制
在运行日志程序的终端中执行:
-
ulimit -f 100M—— 限制单个文件最多 100MB(单位支持 K/M/G,自动换算) -
ulimit -f—— 查看当前值(输出单位是 512 字节块,例如204800表示 100MB) - 再启动日志程序(如
tail -f /var/log/app.log &或自研服务),后续所有由该 shell 启动的进程,一旦尝试将单个文件写满 100MB,就会失败
永久生效:覆盖用户登录会话
编辑 /etc/security/limits.conf,添加两行(以普通用户 appuser 为例):
-
appuser soft fsize 500M—— 软限制,用户可自行调低,但不能超过硬限制 -
appuser hard fsize 500M—— 硬限制,root 才能修改,所有子进程强制遵守 - 保存后,
appuser下次 SSH 登录或新 PAM 会话即生效(systemd 服务需重启或加LimitFSIZE=524288000到 service 文件)
配合日志轮转更可靠
ulimit -f 是底层拦截,但不替代日志管理。建议组合使用:
- 用
logrotate按大小(size 100M)或时间切分日志,保留多份 - 在服务启动脚本开头显式设置:
ulimit -f 200M && exec ./myapp - 避免日志程序自己忽略写入错误——有些工具(如旧版
rsyslog)在EFBIG后可能静默丢弃日志,应检查其 error 日志确认是否报File size limit exceeded
注意边界情况
这个限制只作用于“单个文件”,不影响:
- 多个日志文件总和(比如 app.log、app.log.1、app.log.2)
- 非 shell 启动的守护进程(如 systemd 服务默认不读 limits.conf,需在 unit 文件里配
LimitFSIZE) - 已打开且未 close 的文件描述符——限制只在
open()或首次write()超限时触发,已存在的大文件不会被截断











