My goal:
我的目标:
I would like to redirect the stdout
output of my program foo
to a changing output file depending on the running time of the program.
我想根据程序的运行时间将程序foo的stdout输出重定向到更改的输出文件。
The program foo
itself is listening on a bsd socket for arriving packets and displays information contained in them.
So essentially, after running the program foo
for 10 minutes, I would like to have the stdout
output of
程序foo本身正在监听bsd套接字,以便到达包并显示包中包含的信息。本质上,在运行程序foo 10分钟后,我想要stdout输出
- the first minute inside the file
bar_0.dat
- 文件bar_0.dat中的第一分钟
- the second minute inside the file
bar_1.dat
- 文件bar_1.dat中的第二分钟
- …
- …
- the 10th minute inside the file
bar_9.dat
- 文件里面的第10分钟是bar_9.dat
Is it possible to achieve this in a shell script and if yes, how could I accomplish this?
是否有可能在shell脚本中实现这个目标,如果是,我将如何实现它?
What I have managed so far:
到目前为止,我所管理的:
I only managed this solution, where the program is restarted after each minute with the redirection to a new output file:
我只管理了这个解决方案,在这个解决方案中,程序在每分钟后重新启动,并重定向到一个新的输出文件:
#!/bin/bash
for i in {0..9}
do
timeout 60s foo > "bar_${i}.dat"
done
However, I want the program foo
to be running continuously and not having to restart it, because in the way I have realized it I am loosing some arriving packets (there is a 20-30ms gap between the running instances).
但是,我希望程序foo是连续运行的,而不需要重新启动它,因为我意识到它正在丢失一些到达的包(运行的实例之间有20-30ms的间隔)。
3 个解决方案
#1
1
If foo is producing text output, you might get away with something like:
如果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
If foo is not producing text output, you'll probably want to write foo so that it accepts an external input (eg, a signal) and redirects output on its own. Or, you might just want to use logrotate.
如果foo不产生文本输出,那么您可能想要编写foo,以便它接受外部输入(例如,一个信号)并自行重定向输出。或者,您可能只想使用logrotate。
#2
2
Let the program write to a named pipe (fifo) and then take the output from that pipe and put it in files. In the example here, I start the loop in the background and then immediately start writing to the named pipe:
让程序写入一个命名管道(fifo),然后从该管道获取输出并将其放入文件中。在这里的示例中,我在后台启动循环,然后立即开始编写命名管道:
mkfifo thepipe
for (( i = 0; i < 10; ++i )); do
timeout 60 cat thepipe >"bar_$i.dat"
done &
foo >thepipe
rm -f thepipe
Alternatively, using a process substitution:
或者,使用过程替换:
foo > >(
for (( i = 0; i < 10; ++i )); do
timeout 60 cat >"bar_$i.dat"
done
)
#3
0
You could use an infinite loop and date/time stamp for the file name:
您可以对文件名使用无限循环和日期/时间戳:
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
Also added an error log for any error messages. Not sure how your program is handling stderr
.
还为任何错误消息添加了错误日志。不确定你的程序是如何处理stderr的。
#1
1
If foo is producing text output, you might get away with something like:
如果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
If foo is not producing text output, you'll probably want to write foo so that it accepts an external input (eg, a signal) and redirects output on its own. Or, you might just want to use logrotate.
如果foo不产生文本输出,那么您可能想要编写foo,以便它接受外部输入(例如,一个信号)并自行重定向输出。或者,您可能只想使用logrotate。
#2
2
Let the program write to a named pipe (fifo) and then take the output from that pipe and put it in files. In the example here, I start the loop in the background and then immediately start writing to the named pipe:
让程序写入一个命名管道(fifo),然后从该管道获取输出并将其放入文件中。在这里的示例中,我在后台启动循环,然后立即开始编写命名管道:
mkfifo thepipe
for (( i = 0; i < 10; ++i )); do
timeout 60 cat thepipe >"bar_$i.dat"
done &
foo >thepipe
rm -f thepipe
Alternatively, using a process substitution:
或者,使用过程替换:
foo > >(
for (( i = 0; i < 10; ++i )); do
timeout 60 cat >"bar_$i.dat"
done
)
#3
0
You could use an infinite loop and date/time stamp for the file name:
您可以对文件名使用无限循环和日期/时间戳:
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
Also added an error log for any error messages. Not sure how your program is handling stderr
.
还为任何错误消息添加了错误日志。不确定你的程序是如何处理stderr的。