如何使用bash截断Ubuntu日志文件仅保留末尾指定行数
实现方案
单次执行裁剪(无需额外安装工具)
不要直接用tail -n N 日志文件 > 日志文件,shell会在执行tail前提前清空文件导致日志全丢失,推荐用临时文件原子替换的方式实现:
# 请自行修改要保留的行数和日志文件路径 keep_n=2 log_path="./logfile" tail -n "$keep_n" "$log_path" > "$log_path.tmp" && mv "$log_path.tmp" "$log_path"
如果原文件行数小于等于keep_n,tail会返回文件全部内容,替换后文件内容不会有变化,符合需求。
封装为trimit自定义命令
如果需要频繁使用,可以封装为全局可用的命令,操作步骤如下:
- 执行以下命令创建命令脚本:
sudo tee /usr/local/bin/trimit <<'EOF' #!/bin/bash # 解析入参 while getopts "n:" opt; do case $opt in n) keep_lines=$OPTARG ;; *) echo "用法: trimit -n <要保留的最后行数> <日志文件路径>" && exit 1 ;; esac done shift $((OPTIND-1)) log_file=$1 # 入参校验 if [ -z "$keep_lines" ] || [ -z "$log_file" ] || ! [[ "$keep_lines" =~ ^[0-9]+$ ]]; then echo "用法: trimit -n <要保留的最后行数> <日志文件路径>" echo "示例: trimit -n 2 ./logfile" exit 1 fi if [ ! -f "$log_file" ]; then echo "错误: 文件 $log_file 不存在" exit 1 fi # 仅当实际行数超过保留行数时执行裁剪 current_lines=$(wc -l < "$log_file") if [ "$current_lines" -gt "$keep_lines" ]; then tail -n "$keep_lines" "$log_file" > "$log_file.tmp" && mv "$log_file.tmp" "$log_file" fi EOF
- 给脚本加执行权限:
sudo chmod +x /usr/local/bin/trimit
- 直接使用即可,和你期望的用法完全一致:
trimit -n 2 logfile
注意事项
- 脚本默认将临时文件生成在日志文件同目录下,保证mv操作是原子替换,不会影响正在以追加模式写入的日志程序,几乎所有常规日志输出工具都是用追加模式写日志,不会出现写入异常。
- 如果需要定期自动裁剪,可以添加crontab定时任务,比如每小时执行一次,保留最近1000行日志:
# 执行crontab -e后添加以下行,替换为你自己的日志路径 0 * * * * /usr/local/bin/trimit -n 1000 /path/to/your/logfile
内容的提问来源于stack exchange,提问作者Duncan Marshall
相关产品推荐
相关产品推荐

