【问题标题】:ping several times and get return status for each ipping 几次并获取每个 ip 的返回状态
【发布时间】:2021-11-09 04:50:17
【问题描述】:

我正在尝试同时 ping 192.168.2-254 上的所有 IP 并获取每个 IP 的返回状态。这是我到目前为止所拥有的,但它不起作用,而只是返回 xargs 的状态。任何帮助表示赞赏!我不想用 nmap...

subnet="192.168.1"
num="2"
  while [ "$num" -lt "254" ]; do
     num=$((num+1))
     printf "${subnet}.${num}\n"
  done | xargs -n 1 -I ^ -P 50 ping -c2 -t3

【问题讨论】:

  • ^ 是特殊的,而不是对 shell 有意义,无论它是否是有效的 xargs 语法/参数。它需要转义/引用。
  • 好的,我使用了其他人的部分代码(不要判断我知道你也这样做)。所以我所知道的是 xargs 部分将同时执行 ping 最多同时运行 50 个进程,而 ^ 是命令的一部分。你能帮我改写命令,让我得到 ping 的状态(也许用 '$?' ?"
  • 我不使用xargs,所以我恐怕帮不上忙。
  • 这能回答你的问题吗? how to get exit code when using xargs (parallel)
  • @KamilCuk,我在想 Bourne shell,而不是 Bash 我的坏,^ 与 bash/sh 中的管道相同。

标签: bash ping xargs


【解决方案1】:

@M Horton 这会达到你的目的吗? 在 xargs 字段中使用xargs -n1 -P50 ping -c2

【讨论】:

  • 好吧,问题在于,它会 ping 所有的 ip,然后打印 xargs 的退出代码,而不是每次 ping 一个 ip 时打印 ping 的退出代码
  • 所以我得到2 packets transmitted, 0 packets received, 100.0% packet loss,然后是1
  • 你可以回显出结果 xargs -n1 -P50 ping -c2 ;回声 $?
  • 那仍然会打印出xargs 的退出状态。如果你想分别返回每个ping 的状态,你可以做xargs -n 1 -P 50 sh -c 'ping -c 2 "$1"; echo $?' _ 但是xargs 的用处在这一点上是相当有限的,代码比较复杂,并且为每个运行单独的shell 的开销ping 很重要。
【解决方案2】:

xargs 的公认和记录行为是返回其自己的退出代码,该代码指示您启动的所有子进程发生了什么。智慧;

xargs 以以下状态退出:

0 - 如果成功

123 - 如果命令的任何调用以状态 1-125 退出

124 - 如果命令以状态 255 退出

125 - 如果命令被信号终止

126 - 如果命令无法运行

127 - 如果找不到该命令

1 - 如果发生其他错误。

(来源:GNU xargs man pagePOSIX spec 稍微不那么具体,只是将所有 1-125 归为“无法组装满足指定要求的命令行,返回了一个或多个实用程序调用非零退出状态,或发生其他错误。")

没有简单的方法可以在单个退出代码中传达多个进程的状态(回想一下,该值是单个字节,因此即使您要将返回值编码为位字段,仅指示成功或失败,您仍然只能将其中的八个塞入一个值)但如果我正确理解您的请求,只需在您正在运行的循环中运行ping,并为每个单独运行wait。以下使用 Bash 数组来跟踪各个进程:

declare -a procs

for((num=2; num<254; num++)); do
    ping -c2 -t3 "192.168.1.${num}" &
    procs+=($!)
done
for p in "${procs[@]}"; do
    wait $p; echo $?
done

并行运行的 200 多个 ping 进程的输出会相当嘈杂;也许在第一个done 之后添加&gt;/dev/null。 (将所有内容重定向一次比分别重定向每个ping 更有效。)

这还没有跟踪哪个进程 ID 属于哪个 IP 地址;如果您需要,可能使用关联数组(Bash 4+)或将 IP 地址放入第二个数组并保持对齐,以便 ${ip[x]} 是属于进程 ${procs[x]} 的 IP 地址(例如 MacOS 仍然附带 Bash 3.2.57(1)-release 不支持关联数组)。

这是使用关联数组的重构。

declare -A procs

for((num=2; num<254; num++)); do
    ping -c2 -t3 "192.168.1.${num}" &
    procs[$num]=$!
done >/dev/null
for p in "${!procs[@]}"; do
    wait ${procs[$p]}
    printf "%s:%i\n" "192.169.1.$p" $?
done

【讨论】:

  • 好的,有几件事。那真的很有帮助。其次,我将查看 bash 数组的手册页,因为我不知道它们是如何工作的,而且我通常会通过粘贴其他人编写的我需要先修改的位来搞砸我的代码。第三,我不需要跟踪 pid,但我实际上在 Mac OS 上使用 bash 5.1.8,因为我使用 brew 安装它,然后对所有内容进行符号链接。最后,感谢 TYSM 伙计们的帮助。
  • 添加了关联数组版本。
  • 哦,我刚发现。你知道在第一个代码 sn-p 中它说 for p in... 在那个循环中你可以 printf ${p} 并且它会打印 pid。如果它不适合你让我知道。
  • 有没有办法获得正在处理的 ip 并打印它是否有效?我将此wait $ping &amp;&amp; echo "${} is UP" || echo "${} is DOWN" 添加到您发布的第一个代码 sn-p 中,但我不知道要使用什么变量,也不知道在哪里可以插入一个包含 ip 的变量。
  • 这就是关联数组版本的作用。 (它只打印退出代码,但它应该很容易适应;你已经知道如何了。)
猜你喜欢
  • 1970-01-01
  • 2014-06-09
  • 2011-09-16
  • 2011-06-26
  • 2014-01-31
  • 1970-01-01
  • 2012-03-14
  • 2022-09-27
  • 2020-08-02
相关资源
最近更新 更多