我制作了一个简单的脚本来重新启动路由器,然后显示进度条,直到我的计算机再次建立互联网连接。
运行脚本时,我得到以下输出:
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 秒后放弃。这会导致SIGALRM
ping 无法在内部捕获信号。 (这可以说是一个 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