好的,这里有一个灵感,受到http://en.wikibooks.org/wiki/Bourne_Shell_Scripting/Files_and_streams的启发
创建一个命名管道:
mkfifo /dev/mypipe
将标准输出和错误输出重定向到命名管道:
&> /dev/mypipe
从 mypipe 读取数据并写入文件:
cat < /dev/mypipe > /var/log/log.txt &
当你需要进行日志轮转时,终止进程并旋转日志,然后重新启动该进程。
注意:你可以给命名管道起任何名称,比如 /var/tmp/pipe1, /var/log/pipe, /tmp/abracadabra等等。只需确保在开机之前重新创建管道,在运行日志脚本之前。
另外,也可以不使用cat,而是使用一个简单的脚本文件:
#!/bin/bash
while : ; do
read line
printf "%s\n" "$line"
done
这个脚本保证每次读取换行符后都会有输出。(使用cat命令可能需要等到缓冲区满或遇到EOF时才会开始输出)
最终版本-已测试
重要提示: 请阅读下方@andrew的评论。他指出了几种需要注意的情况。
好了!我终于能够访问我的Linux服务器了。以下是步骤:
第一步:创建此记录器脚本:
#!/bin/bash
LOGFILE="/path/to/log/file"
SEMAPHORE="/path/to/log/file.semaphore"
while : ; do
read line
while [[ -f $SEMAPHORE ]]; do
sleep 1s
done
printf "%s\n" "$line" >> $LOGFILE
done
步骤2: 开始使用录音器:
创建一个命名管道:
mkfifo $PIPENAME
将应用程序的标准输出(STDOUT)和标准错误(STDERR)重定向到命名管道(named pipe):
...things... &> $PIPENAME
开始录制:
/path/to/recorder.sh < $PIPENAME &
你可能希望使用nohup
命令,使得上述命令在退出登录后仍然运行。
完成!
步骤三:如果需要进行日志轮换,请暂停记录器:
touch /path/to/log/file.semaphore
mv /path/to/log/file /path/to/archive/of/log/file
rm /path/to/log/file.semaphore
建议将上述步骤放入自己的脚本中。可以随意更改第二行以使用你想要使用的日志轮转方法。
注意:如果您熟悉C编程,您可能想制作一个短小的C程序来执行recorder.sh
的功能。编译后的C程序肯定比nohup分离bash脚本更轻巧。
注意2: David Newcomb在评论中提供了有用的警告:当记录器未运行时,对管道的写操作将会阻塞并且可能会导致程序无法预测地失败。确保记录器关闭(或轮转)的时间尽可能短。
因此,如果您可以确保旋转发生得非常快,则可以将sleep
(仅接受整数值的内置命令)替换为/bin/sleep
(接受浮点值的程序),并将睡眠时间设置为0.5
或更短。
head --lines=-10 log.txt > log.txt.1
这个命令可以工作吗(其中10
是保留在末尾的一些“合理数量”的行数)?然后,为了清空日志,也许可以使用truncate
命令,不过它是按字节大小而非行数来操作的... - drysdamlogrotate
是一个可以从 Shell 脚本中使用的命令行实用程序。如果你不能使用它,还有什么是不能使用的?你之前使用了cat
、cp
和touch
,那么mv
处于可使用状态吗? - drysdamlogrotate
,但效果相同,文件中出现了很多垃圾字符...也许原因是当我重定向时,底层操作系统知道当前文件描述符的位置,并从那个点继续写入? - Ferenc Deak