简体   繁体   English

设置日志文件的最大行数

[英]Set line maximum of log file

Currently I write a simple logger to log messages from my bash script. 目前,我编写了一个简单的记录器来记录来自bash脚本的消息。 The logger works fine and I simply write the date plus the message in the log file. 记录器工作正常,我只需在日志文件中写上日期和消息即可。 Since the log file will increase, I would like to set the limit of the logger to for example 1000 lines. 由于日志文件将增加,因此我想将记录器的限制设置为例如1000行。 After reaching 1000 lines, it doesn't delete or totally clear the log file. 达到1000行后,它不会删除或完全清除日志文件。 It should truncate the first line and replace it with the new log line. 它应该截断第一行并将其替换为新的日志行。 So the file keeps 1000 lines and doesn't increase further. 因此该文件保留1000行,并且不会进一步增加。 The latest line should always be at the top of the file. 最新行应始终位于文件顶部。 Is there any built in method? 有内置方法吗? Or how could I solve this? 或者我该如何解决?

Your chosen example may not be the best. 您选择的示例可能不是最好的。 As the comments have already pointed out, logrotate is the best tool to keep log file sizes at bay; 正如评论所指出的那样, logrotate是保持日志文件大小不变的最佳工具。 furthermore, a line is not the best unit to measure size. 此外, 生产线不是衡量尺寸的最佳单位。 Those commenters are both right. 这些评论者都是正确的。

However, I take your question at face value and answer it. 但是,我以您的面值回答您的问题。

You can achieve what you want by shell builtins, but it is much faster and simpler to use an external tool like sed . 您可以通过shell内置函数实现所需的功能,但是使用sed这样的外部工具可以更快,更简单地完成任务。 ( awk is another option, but it lacks the -i switch which simplifies your life in this case.) awk是另一种选择,但是它缺少-i开关,在这种情况下可以简化您的生活。)

So, suppose your file exists already and is named script.log then 因此,假设您的文件已经存在,并且名为script.log

maxlines=1000
log_msg='Whatever the log message is'

sed -i -e1i"\\$log_msg" -e$((maxlines))',$d' script.log

does what you want. 做你想要的。

  • -i means modify the given file in place. -i表示就地修改给定文件。
  • -e1i"\\\\$log_msg" means i nsert $log_msg before the first ( 1 ) line. -e1i"\\\\$log_msg"表示 在第一( 1 )行之前插入 $log_msg
  • -e$((maxlines))',$d' means d elete each line from line number $((maxlines)) to the last one ( $ ). -e$((maxlines))',$d'是指d elete从行号的每一行 $((maxlines)) 到最后一个($)。

Why would you want to replace the first line with the new message thereby causing a jump in the order of messages in your log file instead of just deleting the first line and appending the new message, eg simplistically: 为什么要用新消息替换第一行,从而导致日志文件中消息顺序的跳转,而不是仅仅删除第一行并附加新消息,例如,简而言之:

log() {
    tail -999 logfile > tmp &&
    { cat tmp && printf '%s\n' "$*"; } > logfile
}

log "new message"

You don't even need a tmp file if your log file is always small lines, just save the output of the tail in a variable and printf that too. 如果您的日志文件始终是小行,则甚至不需要tmp文件,只需将tail的输出保存在变量中,然后将printf保存。

Note that unlike a sed -i solution, the above will not change the inode, hardlinks, permissions or anything else for logfile - it's the same file as you started with just with updated content, it's not getting replaced with a new file. 请注意,与sed -i解决方案不同,以上内容不会更改logfile索引节点,硬链接,权限或其他任何内容-它与您仅以更新内容开头的文件相同,不会替换为新文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM