疑问
1. 假设有程序不断地输出日志到 /var/log/example.log
# ./test.sh > /var/log/example.log
2. 假设这个程序会运行一年,日志量可能到达5GB.
3. 程序在每次写入新日志的时候,“>”会不会先将 /var/log/example.log 的已有数据读入内存,再追加新的日子? 如果是这样,内存会被大量占用而影响系统性能。
回答
通过 ">" 或 ">>" 输出的日志,不会先读取已有日志到内存中再追加数据,而是直接写入/追加数据。所以不用担心因为已有日志文件过大而导致内存占用。
如果每次追加数据都先读入内存再追加,不仅会导致内存占用高,IO消耗的会非常大,系统不会这么傻。
比如,我们有一个程序一直输出日志到标准输出,而我们把标准输出重定向到了文件。
# /tmp/test.sh > /tmp/output1
每次写入数据,它会往标准输出(FD=1)写入相应数据。从 strace 中可以看到如下条目:
25780 14:36:11.920608 write(1, "Wed Jun 13 14:36:11 HKT 2018\n", 29) = 29 <0.000013>
系统在处理 write() 时,会先找到当前文件(FD=1)对应的 offset,然后从 offset 开始写入数据,并相应地增加 offset.
我们可以通过以下方法来看到FD当前的 offset,它会随着日志的写入而增大:
# cat /proc/25971/fdinfo/1
pos: 1305 <---
flags: 0100001
mnt_id: 59
pos: 1305 <---
flags: 0100001
mnt_id: 59
因此,write()不需要读入原有数据即可在恰当位置写入新数据。
可以查阅 write/lseek 的 man 手册了解更多。