我需要几个网页中包含的整数之和. getPages()
解析整数并将其设置为$subTotal
. getPages()
在背景中的for循环中调用,但是如何获得总和$subTotal
?这是一个替代问题吗?
这是我到目前为止所尝试的.
#!/bin/bash
total=0
getPages(){
subTotal=$(lynx -dump http://"$(printf "%s:%s" $1 $2)"/file.html | awk -F, 'NR==1 {print $1}' | sed 's/\s//g')
total=$(($total+$subTotal))
echo "SubTotal: " $subTotal "Total: " $total
}
# /output/ SubTotal: 22 Total: 22
# /output/ SubTotal: 48 Total: 48 //Note Total should be 70
ARRAY=(
'pf2.server.com:6599'
'pf5.server.com:1199'
...
)
for server in ${ARRAY[@]} ; do
KEY=${server%%:*}
VALUE=${server##*:}
getPages $KEY $VALUE &
done
wait
echo $total
exit 0
# /output/ 0
Run Code Online (Sandbox Code Playgroud)
任何建议表示赞赏
是的,这是一个子壳问题。列表中执行的所有内容... &
(即您的getPages $KEY $VALUE &
)都在子 shell 中执行,这意味着那里的变量更改不会影响父 shell。
我认为可以使用协进程(即通过流进行通信)或者使用GNU parallel或pexec来做一些事情。
这是一个示例pexec
,使用默认输出从单个进程进行通信。我使用了一个更简单的命令,因为无法从此处访问您列出的服务器。这会计算某些网页上的行数并对其进行总结。
ARRAY=(
'www.gmx.de:80'
'www.gmx.net:80'
'www.gmx.at:80'
'www.gmx.li:80'
)
(( total = 0 ))
while read subtotal
do
(( total += subtotal ))
echo "subtotal: $subtotal, total: $total"
done < <(
pexec --normal-redirection --environment hostname --number ${#ARRAY[*]} \
--parameters "${ARRAY[@]}" --shell-command -- '
lynx -dump http://$hostname/index.html | wc -l'
)
echo "total: $total"
Run Code Online (Sandbox Code Playgroud)
我们在这里使用一些技巧:
<( ... )
) 和输入重定向 ( <
) 来代替简单的管道。(( ... ))
算术表达式命令中进行算术运算。我本来可以使用let
, 来代替,但是这样我就必须引用所有内容或避免空格。(你total=$(( total + subtotal ))
也会起作用的。)pexec
:
--normal-redirection
意味着将子进程的所有输出流一起重定向到 的输出流中pexec
。(我不确定如果两个进程想同时写入,这会导致一些混乱。)--environment hostname
将每次执行的不同参数作为环境变量传递。否则它将是一个简单的命令行参数。--number ${#ARRAY[*]}
(--number 4
在我们的例子中)确保所有进程都将并行启动,而不是仅与我们拥有的 CPU 或其他启发式一样多。(这适用于网络往返限制的工作。对于 CPU 限制或带宽限制的工作,数字越小越好。)--shell-command
确保命令将由 shell 评估,而不是尝试直接执行它。这是必要的,因为那里有管道。--parameters "${ARRAY[@]}"
列出实际参数 - 即数组的元素。对于每个命令,都会启动一个单独版本的命令。--
是命令 - 作为单'
引号字符串,以避免$hostname
外壳过早解释其中的内容。该命令简单地下载文件并将其通过管道传输到wc -l
,计算行数。输出示例:
subtotal: 1120, total: 1120
subtotal: 968, total: 2088
subtotal: 1120, total: 3208
subtotal: 1120, total: 4328
total: 4328
Run Code Online (Sandbox Code Playgroud)
ps -f
这是运行时的(部分)输出:
2799 pts/1 Ss 0:03 \_ bash
5427 pts/1 S+ 0:00 \_ /bin/bash ./download-test.sh
5428 pts/1 S+ 0:00 \_ /bin/bash ./download-test.sh
5429 pts/1 S+ 0:00 \_ pexec --number 4 --normal-redirection --environment hostname --parame...
5430 pts/1 S+ 0:00 \_ /bin/sh -c ? lynx -dump http://$hostname/index.html | wc -l
5434 pts/1 S+ 0:00 | \_ lynx -dump http://www.gmx.de:80/index.html
5435 pts/1 S+ 0:00 | \_ wc -l
5431 pts/1 S+ 0:00 \_ /bin/sh -c ? lynx -dump http://$hostname/index.html | wc -l
5436 pts/1 S+ 0:00 | \_ lynx -dump http://www.gmx.net:80/index.html
5437 pts/1 S+ 0:00 | \_ wc -l
5432 pts/1 S+ 0:00 \_ /bin/sh -c ? lynx -dump http://$hostname/index.html | wc -l
5438 pts/1 S+ 0:00 | \_ lynx -dump http://www.gmx.at:80/index.html
5439 pts/1 S+ 0:00 | \_ wc -l
5433 pts/1 S+ 0:00 \_ /bin/sh -c ? lynx -dump http://$hostname/index.html | wc -l
5440 pts/1 S+ 0:00 \_ lynx -dump http://www.gmx.li:80/index.html
5441 pts/1 S+ 0:00 \_ wc -l
Run Code Online (Sandbox Code Playgroud)
我们可以看到,实际上一切都在我的单处理器系统上尽可能并行运行。