핑에서 "알람: 14" 비활성화

핑에서 "알람: 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 1ping이 1초 후에 포기하도록 지시하는 명령이 포함되어 있다는 것입니다. 이로 인해 SIGALRMping이 내부적으로 신호를 캡처하지 못하게 됩니다. (이것은 틀림없이 핑 오류이지만 학문적입니다.) bash 쉘은 이를 128("신호를 잡았습니다" 플래그) + 14(SIGALRM ID) Alarm clock: 14의 종료 상태로 프로세스를 중단합니다 .142

이 문제를 해결하는 방법에는 두 가지가 있습니다.

1) -t 1SIGALRM이 생성되지 않도록 삭제한다. 대신, ping은 (내 경험상) 5초 안에 시간 초과되고 현재 보고 있는 것과 다른 오류 상태를 제공합니다. 지정된 호스트에 연결할 수 없는 경우 68이 발생할 수 있습니다. 이 경우 호스트에 도달하는 즉시 종료되도록 ping에 "-o"를 추가할 수도 있습니다.

2) trap - SIGALRMping 명령 이전에 실행하여 쉘에 신호를 무시하도록 지시합니다. 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

관련 정보