我有以下logrotate脚本
/path/to/folder {
daily
rotate 30
notifempty
sharedscripts
copytruncate
compress
dateext
preremove
if file --mime-type "$1" | grep -q gzip$; then
mkdir -p /path/to/archive/folder && cp $1 $_
fi
endscript
}
我在调试模式下运行此logstash配置
logrotate -d $CONFIG_FILE
通过日志的外观,旋转工作正常,但它甚至没有运行preremove
脚本。我还没有在现场运行这个配置,因为我想在这之前测试它。
logrotate版本3.8.6
我不确定你是否在问为什么preremove没有运行,或者你的脚本是否正常。
我不相信logrotate会运行preremove
脚本,如果它不删除文件(根据-d
)。我设置了一个测试用例并在strace
下运行它。 logrotate -d
找到了需要删除的文件并写道它会删除它们,但没有运行preremove
代码。老实说,这对我来说是有意义的,也是我所期待的,因为preremove
可能会像删除本身一样具有破坏性。
为了执行测试,我认为您需要在另一个目录中重现您的实时环境,并实际运行它。不要使用完整大小的文件,只需使用几行虚拟文件。创建一个脚本来构建测试文件夹,以便您可以轻松地重现测试。使用touch
设置时间戳。例如:
for n in $(seq 1 30); do
cp test.log test.log.$n
gzip test.log.$n
touch -d "now - $n day" test.log.$n.gz
done
grep -q gzip$
错了。 $
将在shell解析中消失。您需要将其括在单引号中。$_
工作。重复目录名称,或在脚本中使用变量。\
。cp -p
,正如有人建议的那样。cp
会很慢。如果您的存档位于同一文件系统中,请考虑使用ln
(而不是ln -s
!)。这将是即时的。file --mime-type
可能工作正常,但坦率地说,在这种情况下,我只是将其基于文件名,因为logrotate会在.gz
将返回file
的任何文件上可靠地附加gzip
。 expr "$1" : '.*gz$'
将为$1
结尾的任何.gz
提供非零数字作为标准输出。它将精确地给出数字0作为不以.gz
结尾的文件名的标准输出。我认为你的条件本身不会成真,你可以在preremove调试之前把它放回去。尝试手动执行if条件并查看。
# file --mime-type * | grep -i *.1
audit.log.1: text/plain
# file --mime-type * | grep -i *.1$
# file --mime-type * | grep -q *.1$
# file --mime-type * | grep -q *.1
你可能会错过some examples中看到的行继续转义
preremove
# debug line
systemd-cat -t "rot-pre-rm" echo "preremove block, file: $1"
if file --mime-type "$1" | grep -q gzip$; then \
cp -p "$1" /path/to/archive/syslog/; \
fi; \
endscript