手动ping失败,但显示了shell脚本

时间:2019-05-07 04:50:00

标签: bash

  1. 手动ping失败,但shell脚本显示

script3.sh

#!/bin/bash
cat host.txt |  while read h
do
    ping -c 1 "$h" | head -1 | cut -d ' ' -f3 | tr -d '()'
    if [ $? -eq 0 ]; then
                echo "$h is up"
    else
                echo "$h is down"
    fi
done

输出

user@APIC> ./script3.sh
10.1.1.1
Nexus01 is up
10.1.1.2
Nexus02 is up
user@APIC>

手动ping显示Nexus01(10.1.1.1)当前处于关闭状态

user@APIC> ping Nexus01 -c 1
PING Nexus01 (10.1.1.1) 56(84) bytes of data.

--- Nexus01 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

user@APIC>

user@APIC> ping Nexus02 -c 1
PING Nexus02 (10.1.1.2) 56(84) bytes of data.
64 bytes from Nexus02 (10.1.1.2): icmp_seq=1 ttl=64 time=0.171 ms

--- Nexus02 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.171/0.171/0.171/0.000 ms
user@APIC>
  1. 我希望得到以下输出。

所需的输出

user@CiscoAPIC> ./script3.sh
Nexus01 - 10.1.1.1 is down
Nexus02 - 10.1.1.2 is up
user@CiscoAPIC>

1 个答案:

答案 0 :(得分:3)

问题

管道的退出代码是管道中 last 命令的退出代码。

考虑:

ping -c 1 "$h" | head -1 | cut -d ' ' -f3 | tr -d '()'
if [ $? -eq 0 ]; then

$?语句看到的退出代码iftr -d '()'的退出代码。您需要退出代码ping

我们可以通过更简单的管道进行演示:

$ false | tr -d '()'; echo $?
0
$ true | tr -d '()'; echo $?
0

在两种情况下,上面的退出代码均为成功(0)。即使false返回退出代码1,也是这样。

解决方案

如果您正在运行bash(而不是sh),则所需的退出代码在外壳程序数组PIPESTATUS中可用。例如:

$ false | tr -d '()'; declare -p PIPESTATUS
declare -a PIPESTATUS=([0]="1" [1]="0")

这表明false以代码1退出了。因此,在您的代码中,替换为:

if [ $? -eq 0 ]; then

具有:

if [ "${PIPESTATUS[0]}" -eq 0 ]; then   # Bash only