我目前正在将监视工具的输出重定向到文件,但是我想做的是根据我的请求(使用键绑定)将此输出重定向到新文件,而不停止所述工具。
就像是
monitor_program | handle_stdout
Wherehandle_stdout
允许我定义一个新文件,将日志放置在特定点的位置。
我知道我可以轻松地编写它,但我想知道是否有任何工具已经允许这样做。
答案1
我会建议一个命名管道。
创建一个管道
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
答案2
基于您的 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
不是您的 shell 中的内置命令(因此它确实会被您按 中断Ctrl+\)。
请注意,就像您的方法一样,SIGQUIT 可能会在错误的时间(在写入系统调用中)传递,从而导致一些数据丢失。
答案3
您可以less
通过输入s要保存到的文件名,然后输入Enter.从如何将 less 中的所有行写入文件?。
答案4
谢谢杰夫·夏勒的回答,我最终得到了这样的东西,它基本上满足了我的需要,让我们称之为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
CtrlCCtrlZ