![如何在shell中清除重定向日志文件内容?](https://linux22.com/image/116374/%E5%A6%82%E4%BD%95%E5%9C%A8shell%E4%B8%AD%E6%B8%85%E9%99%A4%E9%87%8D%E5%AE%9A%E5%90%91%E6%97%A5%E5%BF%97%E6%96%87%E4%BB%B6%E5%86%85%E5%AE%B9%EF%BC%9F.png)
我使用重定向将println
操作输出记录到xxx.log
文件中。但我想将日志信息移动到一个单独的文件,其名称为当前日期,例如2017-08-18.log
通过 crontab。
我尝试使用> xxx.log
shell 命令清除该xxx.log
文件,但在生成新日志时所有内容恢复。
如何清除重定向日志文件?
更新
- 在我执行后
> xxx.log
,xxx.log
文件的大小为0。但是如果我的应用程序打印一些新日志,则xxx.log
不仅包含新的日志信息,还包含以前清除的日志信息。 - 使用后
mv xxx.log xxx2.log
,新的日志信息将写入xxx2.log
。但是如果我使用rm xxx.log
而不是重命名,日志操作将停止。此外,nohup java -jar xxx.jar > xxx.log 2>&1 &
如果您熟悉的话,调用的过程游戏框架、execute file build 通过dist
命令生成jar文件。 ps wx|grep "xxx.*.log
输出:
1)3912 pts/10 S+ 0:00 grep --color=auto xxx.log
2)26234 pts/10 Sl 0:16 /usr/lib/jvm/jdk1.8.0_111/bin/java -Duser.dir=...something ignored... play.core.server.ProdServerStart
(这是进程执行命令)
希望对您有所帮助,再次感谢!
答案1
问题是您的日志文件由写入日志文件的应用程序保持打开状态。如果您截断文件 ( > file.log
),您的应用程序仍会从上次写入的位置开始写入(由于截断,我认为您的文件在此之前将填充 0 字节)。如果您移动该文件,您的应用程序将继续写入该文件,因为一旦打开,其名称就不再重要。如果删除该文件,这些块不会从磁盘中释放,并且应用程序仍会写入它们,即使该文件在您的目录中不再可见。
这是一个经典的场景。您的申请必须:
- 定期重新打开日志文件
- 或检测到它已被截断并重新打开它
- 或者等待一个特殊信号,告诉它“关闭当前的日志文件并重新打开它”
否则,除了重新启动应用程序之外,您无法在外部执行任何操作。然后您将按照以下相同方式进行操作logrotate
:
- 首先将日志文件移动到新名称下
- 可选地
touch
使用旧名称的日志文件,以便该文件存在 - 重新启动应用程序以强制其停止写入旧日志文件并开始写入新日志文件。
答案2
如果你熟悉 Perl,你可以运行这个小脚本:
use POSIX qw(strftime);
$fbase = "tmp-%Y-%m-%d-%H-%M.log";
while(<>)
{
$fnamenew = strftime $fbase, localtime;
if ($fnamenew ne $fname)
{
print "logging to: $fnamenew\n";
$fname = $fnamenew;
close OUT;
open OUT, ">$fname";
}
print OUT $_;
}
像这样使用它:$mycomputation | perl script.pl
.它将所有输入附加到根据给定时间模式构建的文件名,此处tmp-YYYY-MM-DD-HH-MI.log
。在每一新输入行上,都会重建模式并对照旧模式进行检查。如果不同,则输入将通过管道传输到新文件,并关闭旧文件。