我有几个大文件需要传输到本地计算机并进行处理。传输时间大约与文件的处理时间一样长,我想在传输后立即开始处理它。但处理时间可能比传输时间长,而且我不希望进程继续建立,但我想将其限制为某个数字,例如 4。
考虑以下因素:
LIST_OF_LARGE_FILES="file1 file2 file3 file4 ... fileN"
for FILE in $LIST_OF_LARGE_FILES; do
scp user@host:$FILE ./
myCommand $FILE &
done
这将传输每个文件并在传输后开始处理它,同时允许下一个文件开始传输。但是,如果 myCommand $FILE
花费的时间比传输一个文件的时间长得多,这些文件可能会不断堆积并导致本地计算机陷入困境。所以我想将 myCommand
限制为 2-4 个并行实例。随后尝试调用 myCommand
应该对其进行缓冲,直到“槽”打开。在 BASH 中有没有好的方法可以做到这一点(使用 xargs 或其他实用程序是可以接受的)。
更新: 感谢您的帮助,让我们走到了这一步。现在我正在尝试实现以下逻辑:
LIST_OF_LARGE_FILES="file1 file2 file3 file4 ... fileN"
for FILE in $LIST_OF_LARGE_FILES; do
echo "Starting on $FILE" # should go to terminal output
scp user@host:$FILE ./
echo "Processing $FILE" # should go to terminal output
echo $FILE # should go through pipe to parallel
done | parallel myCommand
最佳答案
您可以使用GNU Parallel来实现这一点。只需回显您想要并行运行的命令,它就会为您机器的每个 CPU 核心运行一项作业。
for f in ... ; do
scp ...
echo ./process "$f"
done | parallel
如果您特别想要一次 4 个进程,请使用parallel -j 4
。
如果您想要进度条,请使用parallel --bar
。
或者,仅回显带有空终止的文件名,并将处理命令添加到 parallel
的调用中:
for f in ... ; do
scp ...
printf "%s\0" "$f"
done | parallel -0 -j4 ./process
关于BASH - 传输大文件并在传输后处理限制进程数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51388976/