【问题标题】:Try & Except in a while loop在while循环中尝试和除外
【发布时间】:2023-03-13 08:07:02
【问题描述】:

仍然是编程新手,我正在尝试创建一个脚本来检测远程主机上的端口不可用并更改 iptables 并发送单个通知。

我正在运行 Ubuntu 16.04,我正在使用 Python3,我正在使用 os 模块发送电子邮件和更改 IPtables

我几乎可以让它工作,但是,尝试将它发送到电子邮件一次是一个挑战。

import socket
import sys
import time
import datetime
import os
import logging

#Variables
remote_host = "syslog1"
drop = os.system("iptables-restore < iptables.conf")
undrop = os.system("iptables-restore < DR-iptables.conf")
print ('Starting Syslog DR Plan.')

# run continuously

while True:
    time.sleep(1)
    for remote_port in [514]:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(60)
        now = datetime.datetime.now()
        now_text = now.strftime("%Y-%m-%d %H:%M:%S")
        plco = 0

        try:
            sock.connect((remote_host, remote_port))
            print((now_text, 'Port is Open on', remote_port))


        except:
            socket.timeout
            plco = 1

    if plco == 1:
        undrop
        logging.basicConfig(filename='/var/log/syslog',level=logging.DEBUG , format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
        logging.error('#### Syslog DR Invoked - Immediate action required ####')
        os.system("mail -s '# INVESTIGATE IMMEDIATELY - SYSLOG1 port 514 unreachable #' alert@test.com < ./panic.txt")
        print( 'Port is closed')

    else:
        pass
sock.close()

我怀疑我需要做两件事中的一件,但到目前为止都失败了。一种是将其定义为一个函数,然后调用该函数,然后根据输出将另一个函数设置为电子邮件。

任何人都可以建议去哪里,或者更好的方法来做到这一点(我可能会以困难/错误的方式做事)。

非常感谢

【问题讨论】:

  • 您的 except 块捕获所有异常 - 您应该将其更改为 except socket.timeout:;这样,任何意外行为仍然会引发异常(例如键盘中断)
  • 另外,请确保您发布了可执行代码;你有一些拼写错误。
  • 感谢您的建议。我再看看,让你知道我的进展如何。
  • 谢谢,我现在有了一个以前没有的 if 语句。不幸的是,它仍然发送多封电子邮件。除了重新思考我的生活之外,不知道还能做什么;)
  • “多封电子邮件”是什么意思?如果套接字超时,您的代码应该每秒发送一封电子邮件。这不是你想要的吗?

标签: python-3.x sockets while-loop try-catch


【解决方案1】:

您需要在尝试连接到端口的套接字超时时发送电子邮件的代码。这可以通过使用您的代码来实现:

import socket
import sys
import time
import datetime
import os
import logging

logging.basicConfig(filename='/var/log/syslog', level=logging.DEBUG,
                    format='%(asctime)s %(message)s',
                    datefmt='%m/%d/%Y %I:%M:%S %p')

log = logging.getLogger(__name__)

escalated = False
while True:
    time.sleep(1)
    for remote_port in [514]:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(60)
        now = datetime.datetime.now()
        now_text = now.strftime("%Y-%m-%d %H:%M:%S")


        try:
            sock.connect((remote_host, remote_port))
            print((now_text, 'Port is Open on', remote_port))
            escalated = False


        except (socket.timeout, ConnectionRefusedError):
            if not escalated: 
                log.error('#### Syslog DR Invoked - Immediate action required ####')
                os.system("mail -s '# INVESTIGATE IMMEDIATELY - SYSLOG1 port 514 "
                      "unreachable #' alert@test.com < ./panic.txt")
                escalated = True
            print('Port is closed')

    sock.close()

【讨论】:

  • 非常感谢,理想情况下我想保持脚本运行,这样一旦服务器恢复联机,我就不必重新启动它。现在,我将增加超时时间。感谢您的帮助:)
  • 我给它加了一张支票——它现在只通知你以前是否有效——这意味着在端口再次打开之前你只会收到一封邮件。如果这解决了您的问题,请考虑将答案标记为已接受。
  • 如果您想跟踪多个端口(由您使用的 for 循环建议),您必须在 dict 中跟踪 escalated 值,而不是简单的布尔。否则将无法正常工作。
  • 目前,它只是一个端口,但将来可能需要多个端口。我已经测试过,效果很好,我感激不尽。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-19
  • 2019-03-17
  • 1970-01-01
相关资源
最近更新 更多