Shell 脚本:将程序输出重定向到更改文件

Shell script: Redirect output of program to changing files

我的目标:

我想根据程序的 运行 时间将程序 foostdout 输出重定向到一个不断变化的输出文件。

程序 foo 本身正在监听 bsd 套接字以获取到达的数据包并显示其中包含的信息。
所以基本上,在 运行 程序 foo 10 分钟后,我想要

stdout 输出

是否可以在 shell 脚本中实现此目的?如果可以,我该如何实现?

我目前管理的内容:

我只管理了这个解决方案,程序在每分钟后重新启动并重定向到新的输出文件:

#!/bin/bash
for i in {0..9}
do
  timeout 60s foo > "bar_${i}.dat"
done

但是,我希望程序 foo 连续 运行 而不必重新启动它,因为按照我所意识到的方式,我丢失了一些到达的数据包(有一个 20 运行 个实例之间的 -30 毫秒间隔)。

如果 foo 正在生成文本输出,您可能会逃避这样的事情:

#!/bin/bash

stamp=0
i=0
redirect() {
        if test "$(date +%s)" -gt "$((stamp + 60))"; then
                stamp=$(date +%s)
                exec > "bar_$((i++)).dat"
        fi
}
redirect
./foo | while read line; do
        echo "$line"
        redirect
done

如果 foo 没有产生文本输出,您可能想要编写 foo 以便它接受外部输入(例如,信号)并自行重定向输出。或者,您可能只想使用 logrotate。

您可以使用无限循环和 date/time 标记文件名:

while true
do
    #This date/time stamp is month_day_hour_minute all numbers
    filename="bar_$(date "+%m_%d_%H_%M").dat"
    foo > $filename 2>> error_log
    sleep 60
done

还为任何错误消息添加了错误日志。不确定您的程序如何处理 stderr.

让程序写入命名管道 (fifo),然后从该管道获取输出并将其放入文件中。在这里的示例中,我在后台启动循环,然后立即开始写入命名管道:

mkfifo thepipe

for (( i = 0; i < 10; ++i )); do
    timeout 60 cat thepipe >"bar_$i.dat"
done &

foo >thepipe
rm -f thepipe

或者,使用进程替换:

foo > >( 
    for (( i = 0; i < 10; ++i )); do
        timeout 60 cat >"bar_$i.dat"
    done
)