我有一个包含很多链接的文件。作为一个例子,这是我的文件:
link1
link2
link3
link4
link5
link6
link7
link8
link9
link10
link11
link12
link13
link14
link15
link16
我想在同时运行第 1 个 4 链接的单个终端上运行特定命令。例如我想运行的命令是
wget link1
wget link2
等等..但我想同时运行前 4 个链接。然后,如果其中一个链接下载完成,则应自动提交下一个链接(即 link5)进行下载,依此类推。
我正在寻找一种方法,不需要一个一个地下载链接(使用更多时间),也不需要打开多个终端来将多个单独的链接作为单独的命令提交。任何帮助将非常感激。
答案1
你可以使用 GNU 并行:
parallel --retries 5 -j4 -a file.txt wget {}
这将一次执行 4 个作业并从 读取输入file.txt
。如果某个作业失败,它将重试最多 20 次,然后再继续下一个作业。
答案2
通过xargs
实现-P
保持多个作业并行运行的选项(最常见的实现):
xargs -I {} -P 4 wget --quiet {} <file.txt
正在做没有 xargs
或 GNU parallel
,但使用bash
:
#!/bin/bash
jobs=0
while read -r url; do
if [ "$jobs" -ge 4 ]; then
wait -n
jobs=$(( jobs - 1 ))
fi
wget --quiet "$url" &
jobs=$(( jobs + 1 ))
done <file.txt
wait
这会wget
尽快启动后台任务,直到启动了四个此类作业。然后它会等待其中任何一个结束,wait -n
然后再开始下一个。该jobs
变量保存当前正在运行的作业的数量wget
。
最后,单个wait
调用将阻塞,直到所有作业完成。
正是这一点wait -n
使得它成为一个bash
脚本而不是一个普通的/bin/sh
脚本。
答案3
虽然所有答案都使用parallel
并且xargs
工作正常,但请允许我向您介绍GNU Wget2。它是 Wget 的下一个版本,虽然仍处于 alpha 模式,但它是 Wget 大部分用法的直接替代品。
Wget2 支持多线程下载,因此您只需向它提供文件以及您想要并行下载的数量,让 Wget2 为您处理其余的事情。
来源:GNU Wget 和 GNU Wget2 的 Am 维护者