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 1pingが1秒後に放棄されるように指示するコマンドが含まれていることです。これにより、SIGALRMpingが内部的に信号をキャプチャできなくなります。 (これは間違いなくpingエラーですが学術的です。)bashシェルはこれを128(「シグナルをキャッチしました」フラグ)+ 14(SIGALRM ID)のAlarm clock: 14終了状態にプロセスを中断します。142

この問題を解決する方法は2つあります。

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

関連情報