我有几个大文件需要转移到本地计算机和进程中。传输大约需要处理文件的时间,我想在文件传输后立即开始处理它。但是处理可能要比传输花费更长的时间,并且我不希望流程持续建立,但是我想将其限制为一定数量,例如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
答案 0 :(得分:2)
您可以使用 GNU Parallel 。只需在您要运行的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