用Python ping主机

-1 投票
2 回答
2906 浏览
提问于 2025-04-18 07:55

我刚开始学习Python,对Python的语法还不太熟悉。我的问题是,我想开发一个控制台应用程序,可以对不同的(用户定义的)IP地址进行ping测试。如果某个IP地址能ping通,就简单地打印“主机可用”;如果某个IP地址没有响应,就生成“主机不可用”的消息,并且每5分钟自动执行一次。我试着用for循环来实现,但没能做到我想要的效果。有人能帮我解决这个问题吗?

这是我的代码:

import subprocess
import os
import ctypes # An included library with Python install.
import time
with open(os.devnull, "wb") as limbo:

        for n in xrange(1,10):
                ip="192.168.0.{0}".format(n)
                result=subprocess.Popen(["ping", "-n", "1", "-w", "200", ip],
                        stdout=limbo, stderr=limbo).wait() 
                if result:
                        print ip,ctypes.windll.user32.MessageBoxA(0, "Sorry! Host is not Available.", "Alert!", 1)


                else:
                        print ip, "Host Is Available"



print ("IP Monitor!")
time.sleep(5)

import subprocess
import os
import ctypes # An included library with Python install.
import time
with open(os.devnull, "wb") as limbo:

        for n in xrange(1,10):
                ip="192.168.0.{0}".format(n)
                result=subprocess.Popen(["ping", "-n", "1", "-w", "200", ip],
                        stdout=limbo, stderr=limbo).wait() 
                if result:
                        print ip,ctypes.windll.user32.MessageBoxA(0, "Sorry! Host is not Available.", "Alert!", 1)


                else:
                        print ip, "Host Is Available"



input()

2 个回答

1

如果你想让某个东西一直运行下去,你需要用一个无限循环,而不是用 for 循环。

下面是如何让某个操作执行五次:

for i in (xrange 5):
    ... do stuff ...

或者一般来说,可以对任何数量的项目进行循环:

for personality in ['openness', 'conscientiousness', 'extraversion',
                    'agreeableness', 'neuroticism']:
    ... do stuff ...

下面是如何让某个操作永远执行:

while True:
   ... do stuff ...

或者同样的(但有点难懂),任何为真的条件都可以:

while 1 != 0:
    ... do stuff ...

通常,你会先进行初始化,然后再运行循环。所以,结合 @HaiVu 的回答,你的完整代码大概会是这样的:

import subprocess
import os
import ctypes
import time

print ("IP Monitor!")

while True:
    for n in xrange(1,10):
       ip="192.168.0.{0}".format(n)
       process = subprocess.Popen(["ping", "-n", "1", "-w", "200", ip],
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)
       stdout, stderr = process.communicate()
       if process.returncode != 0:
           print ip,ctypes.windll.user32.MessageBoxA(0,
               "Sorry! Host is not Available.", "Alert!", 1)
       else:
           print ip, "Host Is Available"

   time.sleep(5)

把普通的 print 和特定操作系统的消息框混合在一起似乎有点不太对劲(而且我不知道消息框的 print 会输出什么;没有 IP 地址和时间戳,这个消息框有点没用),但希望这至少能让你入门。

2

你需要在创建 Popen 对象后,立刻调用 communicate() 方法:

from subprocess import Popen, PIPE

def host_is_available(ip):
    '''
    Pings a host and return True if it is available, False if not.
    '''
    cmd = ['ping', '-c', '1', '-t', '1', ip]
    process = Popen(cmd, stdout=PIPE, stderr=PIPE)
    stdout, stderr = process.communicate()
    return process.returncode == 0 # code=0 means available

ip = '192.168.1.2'
if host_is_available(ip):
    print '{} is available'.format(ip)
else:
    print '{} is not available'.format(ip)

讨论

  • Popen() 会创建一个对象(也就是一个进程),但并不会执行命令
  • 要执行这个命令,你需要调用 communicate()
  • communicate() 会返回 stdoutstderr,你可以选择丢弃它们或者使用它们
  • 你不需要打开 os.devnull 来丢弃输出
  • 现在你知道怎么对一个主机进行 ping 测试了,处理多个主机应该不会有问题

撰写回答