我有一个像这样的过程,它会以随机间隔生成预定义数量的文件:
#!/bin/bash
for i in {1..10}
do
sleep $(shuf -i 20-60 -n 1)
echo $i > file_$i.txt
done
我有另一个进程,使用 GNU Parallel 独立运行在每个文件上,如下所示:
parallel wc -l ::: file_{1..10}.txt
正如预期的那样,并行在当前可用的文件上运行。有没有办法让并行等待剩余文件可用并尽快运行?
答案1
1号航站楼:
true >jobqueue; tail -n+0 -f jobqueue | parallel -u
(-u
如果您希望立即在屏幕上输出,则需要此选项。否则输出将延迟到下一个作业完成为止。在这两种情况下,作业都会立即运行)。
2 号航站楼:
#!/bin/bash
for i in {1..10}
do
sleep $(shuf -i 20-60 -n 1)
echo $i > file_$i.txt
echo file_$i.txt >> jobqueue
done
如果这些文件是在 my_dir 中创建的唯一文件,请查看https://www.gnu.org/software/parallel/parallel_examples.html#example-gnu-parallel-as-dir-processor
inotifywait -qmre MOVED_TO -e CLOSE_WRITE --format %w%f my_dir |
parallel -u echo
这样您就不需要该jobqueue
文件了。
答案2
如果文件总是按照 1 到 10 的顺序创建,您可以只测试file_10.txt
.例如
until [ -e file_10.txt ] ; do sleep 20 ; done
parallel wc -l ::: file_{1..10}.txt
否则,您可以计算匹配文件的数量,例如
numfiles=$(find . -name 'file*.txt' | wc -l)
while [ "$numfiles" -lt 10 ] ; do
sleep 20
numfiles=$(find . -name 'file*.txt' | wc -l)
done
parallel wc -l ::: file_{1..10}.txt
(注意:如果任何文件名包含换行符,则管道find
将不起作用,因为会计算行数)wc -l
wc -l
我使用了 20 秒的睡眠时间,因为您的for
循环至少睡眠 20 秒。调整睡眠时间以满足您的需要 - 如果文件创建过程需要很长时间,请增加睡眠时间。如果速度真的很快,就减少它。