是否有一个工具可以根据请求动态地将输出重定向到新文件

是否有一个工具可以根据请求动态地将输出重定向到新文件

我目前正在将监视工具的输出重定向到文件,但是我想做的是根据我的请求(使用键绑定)将此输出重定向到新文件,而不停止所述工具。

就像是

monitor_program | handle_stdout

Wherehandle_stdout允许我定义一个新文件,将日志放置在特定点的位置。

我知道我可以轻松地编写它,但我想知道是否有任何工具已经允许这样做。

答案1

我会建议一个命名管道。

  1. 创建一个管道mkfifo p(如果不是“p”,可以随意命名)

  2. 创建一个“读取器”脚本,从管道读取并写入到您喜欢的任何地方

  3. 告诉监控程序将其日志写入命名管道

下面是一个示例读取器脚本,它从命名管道“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 > preader.shCtrlCCtrlZ

相关内容