gpt4 book ai didi

multithreading - BASH脚本中的多线程ping

转载 作者:行者123 更新时间:2023-12-03 13:16:00 25 4
gpt4 key购买 nike

我到处看看,关于BASH环境中ping的多线程似乎只提出了一个问题。

代码

data=$(<~/Desktop/hosts.txt)
for line in $data
do
ping -c1 $line &> /dev/null &
echo $line is reachable ||
echo $line is down
done

问题在于,它会循环访问文件中的IP地址范围,并在实际上只有24个中的3个可访问时将所有IP地址报告为可访问...

我试图通过向ping中添加 -W 1来减慢扫描速度,但这会导致性能不合格,因此必须使用多线程

最佳答案

按照编码,您有2个独立的,不相关的命令:

# run `ping` and place in background
ping -c1 $line &


# regardless of what the `ping` command does ... always
# print 'reachable` and if that fails print `down`
echo $line is reachable || echo $line is down

我假设您真正想要的是使用 ping的结果(成功或失败)来确定要发出哪个 echo命令;在这种情况下,您需要使用双`&&'替换单个 &,如下所示:
ping -c1 $line &&
echo $line is reachable ||
echo $line is down

尽管这应该提供条件输出,但是现在可以一次在前台执行ping操作。

如果要在后台运行ping(即“多线程”),则 也执行条件打印,则可以将 ping/echo/echo代码放在函数内,然后在 for循环中调用该函数...确保将函数调用放在后台,例如:

ping站点示例:
$ cat pinglist
www.yahoo.com
www.google.com
www.peanut_butter.and_jelly
www.bbc.co.uk
www.not_today_your.not

建议的脚本:
$ cat pinger
#!/bin/bash
function pingit () {

target=${1}

# send stdout/stderr to /dev/null since all we need is the return code

ping -c1 ${target} >/dev/null 2>&1 &&
echo ${target} is reachable ||
echo ${target} is down
}

data=$(<pinglist)

for line in ${data}
do
# call our function and place the call in the background

pingit ${line} &
done

# wait for all outstanding background jobs to complete before continuing

wait

# [optional] let operator know we're done.
echo "Completed."

运行一些示例,请记住输出消息的顺序将根据每个 ping命令完成的速度而变化:
$ pinger
www.yahoo.com is reachable
www.google.com is reachable
www.peanut_butter.and_jelly is down
www.bbc.co.uk is reachable
www.not_today_your.not is down
Completed.

$ pinger
www.peanut_butter.and_jelly is down
www.not_today_your.not is down
www.google.com is reachable
www.bbc.co.uk is reachable
www.yahoo.com is reachable
Completed.

我们将再次运行测试并对输出进行排序,而忽略“已完成”。信息:
$ pinger | egrep -v "Completed" | sort
www.bbc.co.uk is reachable
www.google.com is reachable
www.not_today_your.not is down
www.peanut_butter.and_jelly is down
www.yahoo.com is reachable

!!!请记住,如果要发送的主机列表很长,并且您正在一个较小的框上运行此脚本,则如果启动十万个同时的 ping调用中的十个,则sysadmin可能不会太高兴...并且天堂禁止您犯编码错误,从而产生无限循环的 ping命令。

可以为这种不当行为进行编码(例如,在每X次 ping调用之后限制未完成的 sleep调用的数量或在几秒钟后的 ping编码等),但我将把该编码留作作业;-)

如果您不想打扰某个函数(例如,正在执行快速的命令行循环/ping操作),则可以将 ping/echo/echo括在括号中并在后台运行此构造,尽管您将要决定如何处理与工作相关的消息,例如:
$ data=$(<pinglist)
$ for line in ${data}
do
(ping -c1 ${line} >/dev/null 2>&1 && echo ${line} is reachable || echo ${line} is down) &
done
[1] 12212
[2] 12213
[3] 12214
[4] 12215
[5] 12217
www.google.com is reachable
www.peanut_butter.and_jelly is down
www.not_today_your.not is down
www.bbc.co.uk is reachable
www.yahoo.com is reachable
[5] + Done for line in ${data};do; (ping -c1 ${line} >/dev/null 2>&1 && echo ${line} is reachable || echo ${line} is down) & 2>/dev/null;done
[4] - Done for line in ${data};do; (ping -c1 ${line} >/dev/null 2>&1 && echo ${line} is reachable || echo ${line} is down) & 2>/dev/null;done
[3] Done for line in ${data};do; (ping -c1 ${line} >/dev/null 2>&1 && echo ${line} is reachable || echo ${line} is down) & 2>/dev/null;done
[2] Done for line in ${data};do; (ping -c1 ${line} >/dev/null 2>&1 && echo ${line} is reachable || echo ${line} is down) & 2>/dev/null;done
[1] Done for line in ${data};do; (ping -c1 ${line} >/dev/null 2>&1 && echo ${line} is reachable || echo ${line} is down) & 2>/dev/null;done

掩盖与工作相关的消息的一个选项(kludge?)需要将我们的 ping/echo/echo/&包装在一组大括号中,并将stderr定向到/dev/null ...
$ data=$(<pinglist)
$ for line in ${data}
do
{(ping -c1 ${line} >/dev/null 2>&1 && echo ${line} is reachable || echo ${line} is down) & } 2>/dev/null
done
www.peanut_butter.and_jelly is down
www.not_today_your.not is down
www.google.com is reachable
www.yahoo.com is reachable
www.bbc.co.uk is reachable

...尽管这可能会掩盖您可能感兴趣的一些错误消息,ymmv。

关于multithreading - BASH脚本中的多线程ping,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46023593/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com