Bash 脚本 - 等待所有 xargs 进程完成

Bash 脚本 - 等待所有 xargs 进程完成

我编写了一个小型 bash 脚本,用于抓取 URL 的 XML 站点地图。它使用 xargs 并行检索 5 个 URL。

现在我想在所有的URL都被抓取之后发送一封电子邮件,所以必须等到xargs的所有子进程都完成后才能发送邮件。

我已尝试在 xargs 后使用管道:

#!/bin/bash

wget --quiet --no-cache -O- http://some.url/test.xml | egrep -o "http://some.url[^<]+" | xargs -P 5 -r -n 1 wget --spider | mail...

wait

#!/bin/bash

wget --quiet --no-cache -O- http://some.url/test.xml | egrep -o "http://some.url[^<]+" | xargs -P 5 -r -n 1 wget --spider

wait

mail ... 

这两种方法都不起作用,脚本执行后会立即发送电子邮件。我该如何实现这一点?不幸的是,parallel我的服务器(托管主机)上没有该程序。

答案1

xargs不要使用,而是wget在后台单独生成每个进程,并将后台进程的 PID 收集到列表中。此外,确保将后台进程的输出写入文件。

一旦所有后台进程都已启动,请执行全部列表中的 PID 和wait每个 PID——已经退出的 PID 将不会阻塞wait。现在,希望已经成功等待了所有后台进程,剩下要做的就是将每个后台进程的输出连接到单个文件,然后将其发送到需要输出的任何地方。

类似于这样的(当然,回声是多余的,仅用于演示目的):

#!/bin/bash

mail=$(tempfile)
pids=()
outputs=()

trap "rm -f ${outputs[@]}" EXIT
trap "rm -f $mail" EXIT

for url in $(wget --quiet --no-cache -O- http://some.url/test.xml |\
             egrep -o "http://some.url[^<]+") ; do
  output=$(tempfile)
  wget --spider > $output 2>&1 &
  pids+=($!)
  outputs+=($output)
  echo "Spawned wget and got PID ${pids[-1]}."
done

for pid in ${pids[@]} ; do
  echo "Waiting for PID $pid."
  wait $pid
done

# Concatenate outputs from individual processes into a single file.
for output in ${outputs[@]} ; do cat $output >> $mail ; done

# Mail that file.
< $mail mail -s "All outputs" [email protected]

# end of file.

相关内容