Python检查循环中的条件是否发生变化

时间:2016-04-21 21:15:17

标签: python linux networking

我创建了一个小的python脚本来监视OS(Linux)是否能够ping某个10.0.0.1的ip地址(LAN上的路由器)。第一个脚本工作正常但我必须执行脚本以使其每次都评估条件。

我想我明白这个脚本只是在评估条件后退出。我尝试在下面的第二个示例中包含一个while循环,它评估OS调用的返回并将此函数调用放在循环中以继续检查路由器是否已插回LAN。

定义一个评估ping状态的函数的正确方法是什么?我尝试在最后一个示例中添加一个函数,但它似乎没有更新。

我的目标是运行此脚本一次,当我从网络上拔下它或将其重新插入时检测到10.0.0.1已启动或关闭。

    import os
    import time

    ip = "10.0.0.1"
    response = os.system("ping -c 1 " +ip)

    if response != 0:
            print ip, 'is down'
            time.sleep(3)

    else:
       print ip, 'is up!'

我尝试添加while while循环,但条件似乎没有更新。

    import os
    import time

    ip = "10.0.0.1"
    response = os.system("ping -c 1 " +ip)

    while response != 0:
            print ip, 'is down'
            time.sleep(3)

    else:
    print ip, 'is up!'

我甚至尝试定义一个函数来评估循环的每次迭代的条件。

    import os
    import time


    ip = "10.0.0.1"
    response = os.system("ping -c 1 " +ip)

    def checkstatus():
            response = os.system("ping -c 1 " +ip)

    while response != 0:
            print ip, 'is down'
            time.sleep(3)
            checkstatus()# trying to evaluate if status has changed

    while response != 1:
            print ip, 'is up'
            time.sleep(3)
            checkstatus()# trying to evaluate if status has changed 

修改

这就是我改变脚本的方式,现在它的工作原理。只需要减慢网络无法访问的标准输出。

    import os
    import time

    ip = "10.0.0.1"
    while True:
            response = os.system("ping -c 1 " + ip)
            if response == 0:
                    print'connected'
                    time.sleep(.5)

新输出 NOTICE打印声明已连接 已连接

    --- 10.0.0.1 ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.383/0.383/0.383/0.000 ms
    **connected**
    PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
    64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.308 ms

    --- 10.0.0.1 ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.308/0.308/0.308/0.000 ms
    ***connected***

拔掉插头几秒后的新输出(洪水屏幕)

    connect: Network is unreachable
    connect: Network is unreachable
    connect: Network is unreachable
    connect: Network is unreachable
    connect: Network is unreachable

没有什么太糟糕但担心这将使用许多CPU周期,因为这个脚本会 在树莓派上跑步。

3 个答案:

答案 0 :(得分:2)

您犯的错误是您要查找response中的更改,这些更改不会反映网络状态的变化,除非您通过response = os.system("ping -c 1 " +ip)重复分配。

除了在循环中包含赋值(如DeepSpace所建议),您还可以更改循环检查本身以正确反映网络状态更改(根据您的方法):

while os.system("ping -c 1 " +ip):
    print ip, 'is down'
    time.sleep(3)

同样,在使用checkstatus()时,您需要在循环中包含response = checkstatus()或在检查中使用它:while checkstatus():

您的代码的最后一个版本有几个额外的问题:

  • 通常,程序的返回代码在成功时为0,但它可能有多个非零返回代码,因此您的!= 1检查可能无法正常工作d期望,更好地使用== 0检查。

  • 除非发生连接状态的某个序列,否则序列化的潜在无限while语句实际上不会完成。由于您的目标是只运行一次并找出连接的当前状态,因此代码最好不依赖于此类序列。

也许这样的事情呢?

if os.system("ping -c 1 " +ip):
    print ip, 'is down'
else:
    print ip, 'is up'

或者,如果您更喜欢单行:

print ip, 'is ' + 'down' if os.system("ping -c 1 " +ip) else 'up'

答案 1 :(得分:0)

对于你的第二次尝试(使用该函数),我相信正在发生的事情是response被定义为函数checkstatus的局部变量,它与全局变量{{1}分开。 1}}。要从函数重新分配全局(而不是创建局部变量),请将行response添加到函数体的顶部。

答案 2 :(得分:0)

天真的方式是使用while True

ip = "10.0.0.1"
while True:
    response = os.system("ping -c 1 " + ip)
    if response == 0:
        break  # or do anything else
        time.sleep(3)

更好的方法是让脚本只调用os.system,然后使用crontab或Windows Scheduler每隔X次运行它。