1

これが私の状況の短いバージョンです。現在の ISP が正常に動作していないため、動作していない証拠として ping の成功と失敗をログに記録したいと考えています。Linux を使用しますが、Windows でも問題ありません。私は読んでいますが、私が知る限り、シェルスクリプトまたはPythonコードが最適です.

より詳細に説明すると、Web サイトで 5 秒ごとに 1 回 ping を実行したいと考えています。ping が成功した場合は、ping の正常な結果がファイルに出力されます。ただ、Ping の失敗はタイムアウトが長いので、4 秒程度で ping が成功しなかった場合、ping の試行を停止し、それでも "1 パケット" で完全な ping データを出力するようにプログラムを作成したいと考えています。送信済み、0 受信済み」など、時間がなくなった場合と同様です。

これが私がこれまでに持っているものです:

while true
do
    ping -c1 -w4 www.example.com >> log.txt
    sleep 5
done

残念ながら、2 つの問題があります。まず、「-w4」は、思ったように 4 秒後にタイムアウトしません。そして第二に、「睡眠」はすでに費やされた時間に追加されます. したがって、ping に 3 秒かかる場合、ループには 8 秒かかります。成功、失敗をカウントし、ダウン タイムの割合を出力する別のプログラムを作成するので、失敗時にループに多くの余分な時間がかかることは受け入れられません。

それで、私が必要とするものを考えると、これを行う最善の方法は何ですか? ニーズを満たすために私が改善したことはありますか?助けてくれてありがとう!

PS: シェル スクリプトの作成についてはほとんど何も知りません (端末の操作は得意ですが)。Python についてはさらに詳しく知っています (C++ は知っていますが)。あらかじめお詫び申し上げます。

4

2 に答える 2

1

ループ全体を 5 秒以内に処理したい場合は、ping にかかった時間を知り、5 からそれを引き、その差をスリープ状態にする必要があります。

ping の前後の時間を記録して減算するか、time -pコマンドを使用して を実行することにより、bash からこれを行うことができますping(最初の空白以外の行の 2 番目の列は、のようにフロートとして実時間になります0.01)。

しかし、これはPythonの方が簡単だと思います:

import datetime
import subprocess
import time

while True:
    start = datetime.datetime.now()
    with open('log.txt', 'a+b') as logfile:
        subprocess.call(['ping', '-c1', '-w4', 'www.example.com'], stdout=logfile)
    delta = datetime.datetime.now() - start
    time.sleep(delta.total_seconds())

もちろんping、最大でも 5 秒以内に終了しないと、これは機能しません。負の時間は眠れないからです。明示的に呼び出して、失敗した場合は強制終了 することで解決できます…</p>Popenwait(5)

しかし、必要かどうかに関係なく、常に 5 秒を与える方がはるかに簡単です。

while True:
    with open('log.txt', 'a+b') as logfile:
        ping = subprocess.Popen(['ping', '-c1', '-w4', 'www.example.com'],
                                stdout=logfile)
        time.sleep(5)
        # Not strictly necessary, but it avoids signaling for no reason
        if ping.poll() is None:
            ping.kill()
        ping.wait()
于 2013-09-17T21:44:56.257 に答える
0

代わりに ping をバックグラウンドに置き、別のサブプロセスを使用して待機して強制終了できます。

while true
do
    ping -c1 www.example.com >> log.txt &
    p=$!
    ( sleep 4s; kill -s SIGABRT "$p"; ) &>/dev/null &
    wait "$p"
    sleep 5
done

必要に応じてタイムアウトを調整します。

于 2013-09-17T21:44:07.260 に答える