Bash shell-即使外部更改,也要继续写入相同的文件[名称]

Bash shell-即使外部更改,也要继续写入相同的文件[名称],bash,shell,stdout,Bash,Shell,Stdout,有一个进程不应该被中断,我需要从中捕获标准输出 prg > debug.log 我不能完全修改流程输出数据的方式,尽管我可以根据自己的需要自由包装它的发布。后台,将输出传输到其他命令,等等,这都是一个公平的游戏。进程一旦启动,必须一直运行到时间结束(并且不能被阻止,比如等待fifo清空)。写入速度不是很快,如果文件超过预定义的大小,则可以在任意位置剪切文件 现在,问题是日志会增长到填满所有可用空间,因此必须对其进行轮换,删除/覆盖最旧的实例。现在问题来了 如果我这样做 mv d

有一个进程不应该被中断,我需要从中捕获标准输出

  prg > debug.log
我不能完全修改流程输出数据的方式,尽管我可以根据自己的需要自由包装它的发布。后台,将输出传输到其他命令,等等,这都是一个公平的游戏。进程一旦启动,必须一直运行到时间结束(并且不能被阻止,比如等待fifo清空)。写入速度不是很快,如果文件超过预定义的大小,则可以在任意位置剪切文件

现在,问题是日志会增长到填满所有可用空间,因此必须对其进行轮换,删除/覆盖最旧的实例。现在问题来了

如果我这样做

   mv debug.log debug.log.1
   cp debug.log debug.log.1
   rm debug.log
文件
debug.log
将永远消失,而
debug.log.1
将不断增长

如果我这样做

   mv debug.log debug.log.1
   cp debug.log debug.log.1
   rm debug.log
文件
debug.log.1
不会增长,但
debug.log
将永远消失,程序的所有连续输出都将丢失

是否有某种方法可以使标准输出重定向的行为类似于典型的日志写入-如果文件消失、重命名或诸如此类,请重新创建它


(这都是在busybox下工作的,因此轻量级解决方案是首选。)

如果相关应用程序始终保持日志文件打开,并且无法被告知关闭并重新打开日志文件(正如许多应用程序所能做的那样),那么我能想到的唯一选项就是在适当的位置截断该文件

大概是这样的:

cp debug.log debug.log.1
: > debug.log

您可以使用split命令或任何其他重新打开新文件的命令

prg | split--数字后缀--line=100 debug.log.

原因是,重定向的文件输出被发送到文件句柄,而不是文件名。 因此,进程必须关闭文件句柄并打开一个新的句柄

如果愿意,您可以使用rotatelogs以Apache HTTPD样式执行此操作:

在bash样式中,可以使用脚本:

fn='debug.log'
prg | while IFS='' read in; do
    if ...; then # time or number of lines read or filesize or ...
        i=$((i+1))
        mv "$file" "$fn.$i" # rename the file
        > "$file" # make it empty
    fi
    echo "$in" >> "$file" # fill the file again
done

“典型的日志写入”会让应用程序关闭并重新打开日志文件。您可以尝试在适当的位置复制和截断文件(而不是mv或rm)<代码>cp debug.log debug.log.1;:>debug.log@EtanReisner:截断将起作用。亲爱的上帝,
cp
是邪恶的。它重命名文件,然后以旧名称创建一个新副本,并将写入过程附加到新副本。好吧,没有什么我不能绕开的,截断新的,重命名旧的,重命名新的…@SF。是的,
cp
是奇数。可能有一些标志可以用来让它工作。或者,
install
可能对您更有效(奇怪的是)。