執行 tail -f /var/log/catalina.out 卻報 tail: cannot watch '...': No space left on device,但 df -h、df -hi 均顯示空間充足。真相是:**tail -f 使用 inotify 監控檔案變更,預設每用戶監控上限 fs.inotify.max_user_watches = 8192 已耗盡**。

# tail -f ../logs/catalina.out
tail: cannot watch '../logs/catalina.out': No space left on device
# df -h / df -hi 均有剩餘空間
現代 tail -f(GNU coreutils 7.5+)預設使用 inotify 而非輪詢。每個被監控的檔案/目錄消耗一個 inotify watch。系統預設 fs.inotify.max_user_watches = 8192,大量服務(如 Java 應用、Docker 容器、監控 Agent)同時監控大量日誌檔案時極易耗盡。
/etc/sysctl.conf:vim /etc/sysctl.conffs.inotify.max_user_watches = 524288sysctl -p /etc/sysctl.conftail ../logs/catalina.out 應正常輸出。# 查看當前用戶已用 watches
find /proc/*/fd -lname 'anon_inode:inotify' -printf '%h\n' 2>/dev/null | xargs -I{} sh -c 'ls -l {}/* 2>/dev/null | grep -c inotify' | awk '{sum+=$1} END {print sum}'
# 或簡易估算:每個監控中的檔案/目錄約佔 1 watch
# 系統總上限
cat /proc/sys/fs/inotify/max_user_watches
tail --disable-inotify -f file 強制改用輪詢模式(較耗 CPU)。less +F file 同樣可即時追蹤,不佔用 inotify watch。| 參數 | 預設值 | 說明 |
|---|---|---|
fs.inotify.max_user_watches | 8192 | 每用戶最大監控數(本文調整重點) |
fs.inotify.max_user_instances | 128 | 每用戶最大 inotify 實例數(每 inotify_init() 一個) |
fs.inotify.max_queued_events | 16384 | 佇列最大事件數,防爆佇列丟事件 |
調整 max_user_watches 後,tail -f、filebeat、docker 等依賴 inotify 的工具均受益,徹底解決「空間明明足卻報 No space left」的誤導性錯誤。