使用xargs -P0

使用xargs -P0

我在 Debian 机器上编写了一个脚本来读取 URL 文件并输出每个 URL 的 HTTP 状态代码:

...
while read url
do
    urlstatus=$(curl -H 'Cache-Control: no-cache' -o /dev/null --silent --head --insecure --write-out '%{http_code} ; %{redirect_url}' "$url")
    ...
done < $1

对于包含 100 个 URL 的文件来说还可以,但是对于包含超过 1000 个 URL 的大文件,我的脚本会变得非常慢!

我尝试过在 SO 上找到的几个“提示”:设置 KeepAlive -H 'Keep-Alive: 500',将 GoogleBot 定义为用户代理,--user-agent 'Googlebot/2.1 (+http://www.google.com/bot.html)'并定义连接超时,--connect-timeout 1但什么也没有!

答案1

如果你想并行运行它们,你可以使用 GNU 并行:

#!/usr/bin/env bash

file=$1

status_func () {
    local _url="${1:-/dev/stdin}"
    local _urlstatus
    _urlstatus=$(curl -H 'Cache-Control: no-cache' -o /dev/null --silent --head --insecure --write-out '%{http_code} ; %{redirect_url}' "$_url")
    printf 'Status: %s\n' "$_urlstatus"
}

export -f status_func

cat "$file" | parallel -j20 status_func

-j 选项将设置同时作业的最大数量,默认值是系统上的线程数,但您可能需要调整该数量以获得最佳结果。

请注意,您必须将命令添加到函数中(或者完全添加到单独的脚本中)并导出该函数,以便并行知道它。

如果您要将命令放入独立脚本中,则可以从命令行运行它,如下所示:

cat "$file" | parallel -j20 ./my_script.sh

请注意,此脚本应该只期望通过 stdin 发送一个 URL。


或者,如果您无法使用 GNU 并行,但仍想同时运行多个作业,您可以将它们作为后台作业执行,但很可能希望限制同时进程的数量。这可以通过以下方式完成:

#!/usr/bin/env bash

file=$1

max_bg_procs () {
    local max_number=$((0 + ${1:-0}))
    while :; do
        local current_number=$(jobs -pr | wc -l)
        if [[ $current_number -lt $max_number ]]; then
            break
        fi
        sleep 2
    done
}

status_func () {
    local _url="${1:-/dev/stdin}"
    local _urlstatus
    _urlstatus=$(curl -H 'Cache-Control: no-cache' -o /dev/null --silent --head --insecure --write-out '%{http_code} ; %{redirect_url}' "$_url")
    printf 'Status: %s\n' "$_urlstatus"
}

while IFS= read -rd url; do
    max_bg_procs 20
    status_func "$url" &
done < "$file"

答案2

使用xargs -P0

seq 100 | xargs -I@ echo 'https://example.com?@' > urls.txt
cat urls.txt | xargs -P0 -n1 curl

多快?

没有-P0

time sh -c 'cat urls.txt | xargs -n1 curl'
real    0m 59.79s
user    0m 1.64s
sys     0m 0.99s

-P0

time sh -c 'cat urls.txt | xargs -P0 -n1 curl'
real    0m 0.76s
user    0m 1.26s
sys     0m 0.82s

引用自man xargs

-P 最大进程

并行模式:一次最多运行 maxprocs 次实用程序调用。如果 maxprocs 设置为 0,xargs 将运行尽可能多的进程。

答案3

使用-Z

根据您的用例,另一个潜在的解决方案是-Z标志。当提供多个 URLcurl或让curl 通过指定curl在某个范围上工作的特定语法来自动执行分页等操作时,这非常有用。

该标志的文档-Zhttps://curl.se/docs/manpage.html#-Z

特定范围语法的文档curl位于https://curl.se/docs/manpage.html和 ^F '通配符'。

curl -Z $(cat urls.txt | xargs)

相关内容