라우터를 재부팅한 다음 컴퓨터가 인터넷에 다시 연결될 때까지 진행률 표시줄을 표시하는 간단한 스크립트를 만들었습니다.
스크립트를 실행하면 다음과 같은 결과가 나타납니다.
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이 내부적으로 신호를 캡처하지 못하게 됩니다. (이것은 틀림없이 핑 오류이지만 학문적입니다.) bash 쉘은 이를 128("신호를 잡았습니다" 플래그) + 14(SIGALRM ID) Alarm clock: 14
의 종료 상태로 프로세스를 중단합니다 .142
이 문제를 해결하는 방법에는 두 가지가 있습니다.
1) -t 1
SIGALRM이 생성되지 않도록 삭제한다. 대신, ping은 (내 경험상) 5초 안에 시간 초과되고 현재 보고 있는 것과 다른 오류 상태를 제공합니다. 지정된 호스트에 연결할 수 없는 경우 68이 발생할 수 있습니다. 이 경우 호스트에 도달하는 즉시 종료되도록 ping에 "-o"를 추가할 수도 있습니다.
2) trap - SIGALRM
ping 명령 이전에 실행하여 쉘에 신호를 무시하도록 지시합니다. 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