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

时间:2018-06-05 13:31:57

标签: linux bash shell redirect stdout

我的目标:

我想将程序stdout的{​​{1}}输出重定向到更改的输出文件,具体取决于程序的运行时间。

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

  • 文件stdout
  • 内的第一分钟
  • 文件bar_0.dat
  • 内的第二分钟
  • ...
  • 文件bar_1.dat
  • 内的第10分钟

是否有可能在shell脚本中实现这一点,如果是,我该如何实现?

到目前为止我管理的内容:

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

bar_9.dat

但是,我希望程序#!/bin/bash for i in {0..9} do timeout 60s foo > "bar_${i}.dat" done 能够连续运行而不必重新启动它,因为我已经意识到这一点,我正在丢失一些到达的数据包(运行之间存在20-30ms的差距)实例)。

3 个答案:

答案 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