Answers:
我建议一个命名管道。
创建管道mkfifo p
(任意调用,如果不是“ p”,则调用它)
创建一个“读取器”脚本,该脚本从管道读取并在您喜欢的任何地方写入
告诉监视程序将其日志写入命名管道
这是一个示例读取器脚本,该脚本从命名管道“ p”读取并将数据写入索引的“ mylog”文件:
#!/bin/sh
INDEX=0
switchlog() {
read INDEX < newindex
echo now writing to "mylog.$INDEX"
}
trap switchlog USR1
while :
do
cat p >> mylog."$INDEX"
done
read
,printf
而不仅仅是cat <p >> mylog."$INDEX"
?
建立在您的SIGINT想法的基础上,在这里使用SIGQUIT(Ctrl+\)仍然Ctrl+C可以停止整个事情:
(trap '' QUIT; monitor_command) | (
trap : QUIT
ulimit -c 0 # prevent core dump so SIGQUIT behaves like SIGINT
# for cat
n=0; while n=$((n+1)); file=output.$n.log; do
printf 'Outputting to "%s"\n' "$file"
cat > "$file"
done)
假定cat
外壳中没有内置的东西(因此按确实会打断它Ctrl+\)。
请注意,就像您的方法一样,SIGQUIT有可能在错误的时间(在写入系统调用中)交付,从而导致某些数据丢失。
您可能可以less
通过键入s要保存到的文件名,然后从那里使用并保存Enter。从我怎样写都行从少到一个文件?。
如果不了解您的“请求”,就不可能回答。如果基于文件大小或间隔,则可以使用rotatelogs(应该与Apache httpd捆绑在一起)。
多亏了Jeff Schaller的回答,我最终得到了这样的东西,基本上可以满足我的需要,我们称之为reader.sh
:
#!/bin/sh
INDEX=0
LOGNAME="$INDEX.log"
switchlog() {
local custom_name
read -p "Add log name: " custom_name
INDEX=$((INDEX+1))
LOGNAME="$(printf "%03d" $INDEX).$custom_name.log"
echo now writing to $LOGNAME
}
trap switchlog INT
switchlog
while :
do
read foo < p
printf "%s\n" "$foo" >> "$LOGNAME"
done
然后,仅需使用创建一个命名管道mkfifo p
,并在monitor_program > p
和reader.sh
运行两个终端上使用它们即可。然后,我可以使用Ctrl+ 停止阅读器设置新日志C,然后输入新名称。Ctrl+ Z,然后照常停止并杀死它。
logrotate
手动运行带有自定义配置文件的文件,具体取决于monitor_program的行为,但这有点黑。