我的目标:
我想将程序stdout
的{{1}}输出重定向到更改的输出文件,具体取决于程序的运行时间。
程序foo
本身正在侦听bsd套接字以获取到达的数据包并显示其中包含的信息。
基本上,在运行程序foo
10分钟后,我希望foo
输出
stdout
bar_0.dat
bar_1.dat
是否有可能在shell脚本中实现这一点,如果是,我该如何实现?
到目前为止我管理的内容:
我只管理了这个解决方案,在每分钟后重新启动程序并重定向到新的输出文件:
bar_9.dat
但是,我希望程序#!/bin/bash
for i in {0..9}
do
timeout 60s foo > "bar_${i}.dat"
done
能够连续运行而不必重新启动它,因为我已经意识到这一点,我正在丢失一些到达的数据包(运行之间存在20-30ms的差距)实例)。
答案 0 :(得分:2)
让程序写入命名管道(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
)
答案 1 :(得分:1)
如果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。
答案 2 :(得分:0)
您可以为文件名使用无限循环和日期/时间戳:
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
。