【问题标题】:BASH - transfer large files and process after transfer limiting the number of processesBASH - 传输限制进程数后传输大文件和进程
【发布时间】:2018-07-17 19:33:21
【问题描述】:

我有几个大文件需要传输到本地计算机并进行处理。传输大约需要处理文件的时间,我想在传输后立即开始处理它。但处理时间可能比传输时间长,我不希望进程继续增加,但我想将其限制为某个数字,比如 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

【问题讨论】:

    标签: bash parallel-processing background


    【解决方案1】:

    您可以为此使用 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 
    

    【讨论】:

    • 谢谢马克!我认为这个结构正是我所追求的。唯一额外的事情是,如果我还可以在 for 循环中回显一些将被发送到终端输出而不是并行的语句。查看更新后的帖子。
    • 试试echo XYZ > /dev/tty吧?
    • 如果脚本并不总是在终端中运行(例如 cron)。然后改用echo XYZ >&2
    猜你喜欢
    • 1970-01-01
    • 2018-02-24
    • 2011-08-27
    • 1970-01-01
    • 2011-01-06
    • 2011-12-19
    • 1970-01-01
    • 2023-04-07
    • 2018-04-16
    相关资源
    最近更新 更多