xargs -n 选项以实现并行性和更少的处理时间

xargs -n option to achieve parallelism and less processing time

我想了解如何使用 xargs -n 选项循环 csv 文件和 运行 CURL 操作将输出收集到文件以实现更快的处理时间.

示例:

我需要根据带有 URI(其中 1000 个)的 CSV 文件检查网页运行状况。

URI.csv

signup
account
edit
close

我正在尝试并行检查它们的状态,使用:

cat URI.csv | xargs -n1 -I {} /bin/bash -c 'curl -I http://localhost/{} &> /dev/null && echo "{},Online">>healthcheck.log || echo "{},Offline">>healthcheck.log '

我可以通过制作 -n2 来加快处理速度吗?我知道我可以使用 -P4 之类的东西来实现并行性,但是无法理解 -n 如何用于我的用例。

考虑以下代码:

xargs -d $'\n' -P2 -n2 \
  /bin/bash -c '
    for arg do
      if curl --fail -I "http://localhost/$arg" &>/dev/null; then
        printf "%s,Online\n" "$arg"
      else
        printf "%s,Offline\n" "$arg"
      fi
    done
  ' _ >>healthcheck.log <URI.csv
  • xargs -d $'\n' 告诉 GNU xargs 操作 line-by-line,而不是将你的输入文件拆分成单词,试图遵守引号,或者使用比你想象的实际复杂得多的解析想要。
  • xargs -P 2 指定您一次 运行 两个进程。随心所欲地调整它。
  • xargs -n 2 指定为每个进程提供两个指向 运行 的 URL。随心所欲地调整它。
  • bash -c '...' _ arg1 arg2 运行s 脚本 ... _[=18=], arg1</code>, [= <code> 中的 21=] 等。因此,由 xargs 附加的参数成为脚本的位置参数,for arg do 对其进行迭代。
  • foo && bar || baz 有点像 if foo; then bar; else baz; fi,但不完全相同。参见 BashPitfalls #22
  • 请注意,对于整个复合命令,我们只打开 healthcheck.log 写入 一次 ,而不是每次我们想要 re-opening 文件向其中写入一行。

使用 GNU Parallel 看起来像这样:

cat URI.csv |
  parallel -j100 'curl -I http://localhost/{} &> /dev/null && echo {}",Online" || echo {}",Offline"' >>healthcheck.log

或更容易阅读:

#!/bin/bash

doit() {
  if curl -I http://localhost/"" &> /dev/null ; then
    echo ",Online"
  else
    echo ",Offline"
  fi
}
export -f doit
cat URI.csv | parallel -j100 doit >>healthcheck.log

-j100 调整为您想要 运行 并行作业的数量。

通过使用 GNU Parallel,作业将 运行 并行,但 healthcheck.log 的输出将被序列化,您永远不会看到竞争条件,即两个作业同时写入日志这会弄乱日志文件。在这个例子中accountedit同时写了:

signup,Online
accouedit,Online
nt,Offline
close,Online

GNU Parallel 的输出永远不会发生这种情况。