禁止 ping 中的“闹钟:14”

禁止 ping 中的“闹钟:14”

我制作了一个简单的脚本来重新启动路由器,然后显示进度条,直到我的计算机再次建立互联网连接。

运行脚本时,我得到以下输出:

The router is now rebooting...
############################################bin/reboot_router: line 48:  4758 Alarm clock: 14         ping -Q -c 1 -t 1 google.com >&/dev/null
#bin/reboot_router: line 48:  4761 Alarm clock: 14         ping -Q -c 1 -t 1 google.com >&/dev/null
#bin/reboot_router: line 48:  4763 Alarm clock: 14         ping -Q -c 1 -t 1 google.com >&/dev/null
#####bin/reboot_router: line 48:  4773 Alarm clock: 14         ping -Q -c 1 -t 1 google.com >&/dev/null
#bin/reboot_router: line 48:  4775 Alarm clock: 14         ping -Q -c 1 -t 1 google.com >&/dev/null
##bin/reboot_router: line 48:  4777 Alarm clock: 14         ping -Q -c 1 -t 1 google.com >&/dev/null
#

我想抑制该Alarm clock: 14事物的出现,因此输出变为:

The router is now rebooting...
#######################################################

脚本的相关部分是:

#!/bin/bash

COLUMNS=$(tput cols)

# Reboot router code here

echo 'The router is now rebooting...'

min_time=60
max_time=120
start_time=$SECONDS
time=0
progress=0

until [[ $min_time -lt $time ]] && ping -Q -c 1 -t 1 google.com &> /dev/null; do
    let time=SECONDS-start_time
    let new_progress=COLUMNS*time/max_time
    let diff=new_progress-progress
    let progress=new_progress
    for((i=0; i<diff; i++)); do
        echo -n '#'
    done
    sleep 1
done

echo

答案1

你的问题是你的 ping 命令包含-t 1告诉 ping 在 1 秒后放弃。这会导致SIGALRMping 无法在内部捕获信号。 (这可以说是一个 ping 错误,但这是学术性的)。 bash shell 将此报告为Alarm clock: 14并中止进程,退出状态为142; 128(这是“我捕获到一个信号”标志)+ 14(SIGALRM id)。

有两种方法可以解决这个问题:

1) 删除-t 1以便不生成SIGALRM。相反,ping 将在(根据我的经验)5 秒内超时,并给出与您当前看到的不同的错误状态;如果无法到达指定的主机,则可能为 68。在这种情况下,您可能还需要在 ping 中添加“-o”,以便在主机可访问时立即终止。

2)trap - SIGALRM在 ping 命令之前执行,告诉 shell 忽略该信号。 1秒超时仍会发生,退出状态仍为142。至少,我在运行 Yosemite (10.10.5) 的 iMac 上进行了测试。

答案2

将其拉ping入它自己的函数中,并在其中对结果执行任何您想要的操作。最后根据函数内部的状态返回 0 或 1。

ping_func(){
    results=$(ping -c 1 -t 1 google.com &> /dev/null)
    return $?
}

until [[ $min_time -lt $time ]] && ping_func; do
    let time=SECONDS-start_time
    let new_progress=COLUMNS*time/max_time
    let diff=new_progress-progress
    let progress=new_progress
    for((i=0; i<diff; i++)); do
        echo -n '#'
    done
    sleep 1
done

echo

case/switch或者,如果您需要在从 获取不同状态时采取不同的操作,则可以在函数中使用更详细的函数ping

case "$status" in
    1) return 0 ## success   ;;
    0) return 1 ## fail      ;;
    *) ### do something else ;;
esac

相关内容