栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

linux设置定时发送邮件[定时获取ip并通过smtp邮件发送][Linux cron排期工具][python获取ubuntu的ip]

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

linux设置定时发送邮件[定时获取ip并通过smtp邮件发送][Linux cron排期工具][python获取ubuntu的ip]

linux设置定时发送邮件
[定时获取ip并通过smtp邮件发送]
[Linux cron排期工具]
[python获取ubuntu的ip]

文章目录
  • 前言
  • 一、使用smtp发送邮件
    • 1.邮箱设置步骤
    • 2.自动化邮件发送
  • 二、问题解决方案
    • 1.安装postfix
    • 2.ifconfig路径问题(ifconfig not found)
  • 总结


前言

在使用远程工具的时候,第一步是需要知道目标主机的ip,随着DHCP的广泛使用,ip变的灵活的同时也给远程操作带来了些许烦恼。经常因为断电、断网、移机等操作使得远程主机的ip地址发生变化。相信不少人都遇到过下面的情况

下面,本文将介绍一种定时获取远程主机ip的方法。
提示:该方法将用到smtp邮件和python脚本,当然也可以使用shell脚本,本文暂不涉及shell脚本方法


提示:以下是本篇文章正文内容,下面案例可供参考

一、使用smtp发送邮件

提示:本方法非原创,引用地址贴在下面,为防止地址失效,在这里将重述引文方法(此处不完全是对引文的copy,有较多补充之处)
引文地址:https://zhuanlan.zhihu.com/p/338190964

这里使用python的smtp包发送邮件,需要一个支持smtp的邮箱(常见的邮箱都支持smtp),以sina.com邮箱为例:

import smtplib
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from time import asctime

def send_an_email(email_content): # email_content是一个字符串
    mail_host = "smtp.sina.com" # 这个去邮箱找
    mail_user = 发送的邮箱地址
    mail_auth_code = 授权码,不是邮箱的登陆密码
    mail_sender = mail_user # 用mail_user 作为发送人
    mail_receivers = [收件人list]
    message = MIMEMultipart()
    message['From'] = Header(mail_sender)  # 寄件人
    message['Subject'] = Header("主题名字")
    message.attach(MIMEText(asctime(), 'plain', 'utf-8'))
    message.attach(MIMEText(email_content, 'plain', 'utf-8'))
    print("message is {}".format(message.as_string())) # debug用
    smtpObj = smtplib.SMTP(mail_host)
    # smtpObj.set_debuglevel(1) # 同样是debug用的
    smtpObj.login(mail_user, mail_auth_code) # 登陆
    smtpObj.sendmail(mail_sender, mail_receivers, message.as_string()) # 真正发送邮件就是这里

使用该脚本之前,还需要对邮箱进行设置

1.邮箱设置步骤

1.登陆自己的http://sina.com邮箱,找到设置,找到客户端pop/imap/smtp。从这里找到smtp服务器的地址,以及生成授权码。

2.在邮箱设置里面获得授权码:

3.将邮箱配置好之后,可以调用这个send_an_email函数。自己修改email_content和Header,查看发送效果。通过smtp发送了一封邮件:

2.自动化邮件发送

虽然前面实现了自动获取ip地址,也实现了通过python的smtp包进行邮件发送。但是离智能还是差一点:所有过程都得人工去运行这个脚本。我们希望的是:ipv6地址一旦变化,就给我发邮件,但是又不要时时刻刻给我发邮件。

实现思路是监控服务器的ipv6地址,将当前的ipv6地址存储下来,每隔一个固定时间就检查一下服务器ipv6地址,如果没有变化,则不发送邮件,如果有变化,则发送邮件。按照这个思路对获取ipv6地址的代码进行改造:

def get_temp_ip(current_ip):
    temp_ip_json_path = "/var/tmp/ip.json"
    if not os.path.exists(temp_ip_json_path):
        print("No {}, dump it.".format(temp_ip_json_path))
        with open(temp_ip_json_path, 'w') as jo:
            json.dump(current_ip, jo)
            return True, current_ip

    else:
        with open(temp_ip_json_path, 'r') as jo:
            origin_ip = json.load(jo)
        if origin_ip == current_ip:
            print("Current ip {} do not change, no need to send".format(current_ip))
            return False, current_ip
        else:
            print("The ip updated from {} to {}, update it.".format(origin_ip, current_ip))
            os.remove(temp_ip_json_path)
            with open(temp_ip_json_path, 'w') as jo:
                json.dump(current_ip, jo)
                return True, current_ip


def get_ip():
    hostname = socket.gethostname()
    addr_infos = socket.getaddrinfo(hostname, None)
    ips = set([addr_info[-1][0] for addr_info in addr_infos])
    global_ips = [ip for ip in ips]
    whether_to_send, send_ip = get_temp_ip(global_ips)
    send_ip = json.dumps(send_ip)
    return whether_to_send, send_ip

如果您的代码执行的结果为127.0.1.1而不是该有的192.168.33.2这种正常ip的话,请往下看
提示:上述的get_ip()方法不适用于Ubuntu系统,如果您是Ubuntu系统请放弃使用上述的socket方法,下面给出Ubuntu系统适用的get_ip()方法,那就是使用ifconfig命令行的方式获取本地ip

def get_ip():
    # 使用os.popen()函数执行ifconfig命令,结果为file对象,将其传入cmd_file保存
    cmd_file = os.popen('ifconfig')
    # 使用file对象的read()方法获取cmd_file的内容
    cmd_result = cmd_file.read()
    # 构造用于匹配IP的匹配模式(这里的pattern模式自己根据正则表达式修改成适合与自己系统的语言,因为不同系统使用的语言不同,英文和中文会有差异,正则表达式也不同)
    pattern = re.compile(r'(inet )(d{1,3}.d{1,3}.d{1,3}.d{1,3})')
    # 使用re模块的findall函数匹配
    ip_list = re.findall(pattern, cmd_result)
    # 循环打印获取到的IP
    ips = []
    for ip in ip_list:
        # 因为re.findall返回的是列表元组的形式,在后续的json文件写入时是列表列表的形式
        ips.append(list(ip))
    global_ips = [ip for ip in ips]
    whether_to_send, send_ip = get_temp_ip(global_ips)
    send_ip = json.dumps(send_ip)
    return whether_to_send, send_ip

先判断是否有/var/tmp/ip.json文件。如果没有这个文件,就将当前ipv6地址保存,并且发送邮件。如果存在就读取其中的ipv6地址,如果当前ipv6和保存的ipv6地址一样,就继续等待下一次检查,如果不一样就更新ip.json文件并且发送邮件。 为了脚本可以可以执行,还要给脚本添加上main:

if __name__ == "__main__":
    whether_to_send, global_ips = get_ip()
    if whether_to_send:
        send_an_email(global_ips)
    else:
        print("wait and no send")

还要给脚本添加上可执行权限:

sudo chmod +x send_ip_to_mailbox.py

使用到linux的排程工具cron将任务排期自动执行
在管理员命令行下执行crontab -e 进行编辑

crontab -e

根据自己的情况选择熟悉的编辑器

这里配置的是每隔1分钟执行一次ipv6地址检查。

*/1 * * * * /usr/bin/python3 /abs_path/send_ip_to_mailbox.py >> /abs_path/send.log

1.上述配置信息中 */1表示每分钟,*/60表示每60分钟
后面四个* * * *分别表示 时、日、月、周,具体内容可以自行查询cron表达式
2.紧接着后面的/usr/bin/python3 是执行该文件的环境,因为是py文件,所以需要使用python3去执行,自己根据需要选择自己的环境就行
3.紧接着后面的/abs_path/send_ip_to_mailbox.py是你的脚本文件,要执行的文件
4.紧接着 >> /abs_path/send.log是执行脚本的日志输出

配置好cron后需要对其进行重启

sudo service cron restart

重启后查询状态

sudo service cron status


这种active状态就可以了


截至到现在,您的定期发送ip功能应该可以正常使用了
但是~~~~~~
就有某些是不能正常使用的,那就接着往下看吧!!!!

这有可能是您的ifconfig命令找不到()

二、问题解决方案 1.安装postfix

如果您的代码用python执行的结果是正常,但是在cron排期工具里执行一直是[],你发现这太诡异了,在log文件里还看不到为什么,也没报异常
使用service cron status可以看到(CRON) info (No MTA installed, discarding output)的提示

service cron status


这是需要您安装postfix才能看到

那下面就来安装吧 安装命令:sudo apt-get install postfix

sudo apt-get install postfix

安装过程中会让你选择一种Postfix配置类型。一般情况下,我们需要选择第二种类型:Internet Site。

然后下一步就可以了
安装完成后会有一个提示:您在 /var/mail/root 中有新邮件

然后去这里边看就行了
使用cat命令查看 cat /var/mail/root

cat /var/mail/root

看到是什么问题就解决什么问题就好了
如果您的问题是ifconfig not found 请您往下看

2.ifconfig路径问题(ifconfig not found)

如果执行上述的cat /var/mail/root 看到的问题中有 ifconfig not found (如下所示)

那可能是您的cron路径下找不到ifconfig,所以需要我们将ifconfig命令改为绝对路径形式
将get_ip()方法里的ifconfig改为/sbin/ifconfig

代码如下:

def get_ip():
    # 使用os.popen()函数执行ifconfig命令,结果为file对象,将其传入cmd_file保存
    cmd_file = os.popen('/sbin/ifconfig')
    # 使用file对象的read()方法获取cmd_file的内容
    cmd_result = cmd_file.read()
    # 构造用于匹配IP的匹配模式(这里的pattern模式自己根据正则表达式修改成适合与自己系统的语言,因为不同系统使用的语言不同,英文和中文会有差异,正则表达式也不同)
    pattern = re.compile(r'(inet )(d{1,3}.d{1,3}.d{1,3}.d{1,3})')
    # 使用re模块的findall函数匹配
    ip_list = re.findall(pattern, cmd_result)
    # 循环打印获取到的IP
    ips = []
    for ip in ip_list:
        # 因为re.findall返回的是列表元组的形式,在后续的json文件写入时是列表列表的形式
        ips.append(list(ip))
    global_ips = [ip for ip in ips]
    whether_to_send, send_ip = get_temp_ip(global_ips)
    send_ip = json.dumps(send_ip)
    return whether_to_send, send_ip

总结

该方法适合有python基础,linux服务器ip经常改变却只能远程的朋友们,此外还需要去了解下cron排期工具。希望上述内容能够帮到您


都看到这儿了~ 有用的话~点个攒呗^- ^

最后,附上py文件的全部内容

import json
import os
import platform
import re
import smtplib
import socket
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from time import asctime


def send_an_email(global_ips, cmd_result):  # email_content是一个字符串
    mail_host = "smtp.163.com"  # 这个去邮箱找
    mail_user = "taouchen@163.com"
    mail_auth_code = "DBTGHMGPWNKUHIXI"
    mail_sender = mail_user  # 用mail_user 作为发送人
    mail_receivers = ["chentao.edu@aliyun.com;"]
    message = MIMEMultipart()
    message['From'] = Header(mail_sender)  # 寄件人
    message['Subject'] = Header("3090服务器ip")
    message.attach(MIMEText(asctime(), 'plain', 'utf-8'))
    message.attach(MIMEText(global_ips, 'plain', 'utf-8'))
    email_content = cmd_result
    message.attach(MIMEText(email_content, 'plain', 'utf-8'))
    print("message is {}".format(message.as_string()))  # debug用
    smtpObj = smtplib.SMTP(mail_host)
    # smtpObj.set_debuglevel(1) # 同样是debug用的
    smtpObj.login(mail_user, mail_auth_code)  # 登陆
    smtpObj.sendmail(mail_sender, mail_receivers, message.as_string())  # 真正发送邮件就是这里


def get_temp_ip(current_ip):
    if platform.system().lower() == 'windows':
        path = "\ip.json"
    elif platform.system().lower() == 'linux':
        path = "/ip.json"

    current_directory = os.path.dirname(os.path.abspath(__file__))
    # temp_ip_json_path = "/smtp/ip.json"
    temp_ip_json_path = current_directory + path
    if not os.path.exists(temp_ip_json_path):
        print("No {}, dump it.".format(temp_ip_json_path))
        with open(temp_ip_json_path, 'w') as jo:
            json.dump(current_ip, jo)
            return True, current_ip
    else:
        with open(temp_ip_json_path, 'r') as jo:
            origin_ip = json.load(jo)
        if origin_ip == current_ip:
            print("Current ip {} do not change, no need to send".format(current_ip))
            return False, current_ip
        else:
            print("The ip updated from {} to {}, update it.".format(origin_ip, current_ip))
            os.remove(temp_ip_json_path)
            with open(temp_ip_json_path, 'w') as jo:
                json.dump(current_ip, jo)
                return True, current_ip


def get_ip():
    # 下面的方法获取不到Ubuntu的ip
    """
    hostname = socket.gethostname()
    addr_infos = socket.getaddrinfo(hostname, None)
    ips = set([addr_info[-1][0] for addr_info in addr_infos])
    """

    # 使用os.popen()函数执行ifconfig命令,结果为file对象,将其传入cmd_file保存
    cmd_file = os.popen('ifconfig')
    if platform.system().lower() == 'windows':
        cmd_file = os.popen('ipconfig')
    elif platform.system().lower() == 'linux':
        cmd_file = os.popen('/sbin/ifconfig')

    # 使用file对象的read()方法获取cmd_file的内容
    cmd_result = cmd_file.read()
    # print(cmd_result)
    # 构造用于匹配IP的匹配模式
    pattern = re.compile(r'(inet )(d{1,3}.d{1,3}.d{1,3}.d{1,3})')
    if platform.system().lower() == 'windows':
        pattern = re.compile(r'(IPv4.*?)(d{1,3}.d{1,3}.d{1,3}.d{1,3})')
    elif platform.system().lower() == 'linux':
        pattern = re.compile(r'(inet )(d{1,3}.d{1,3}.d{1,3}.d{1,3})')

    # 使用re模块的findall函数匹配
    ip_list = re.findall(pattern, cmd_result)
    # 循环打印获取到的IP
    ips = []
    for ip in ip_list:
        # 因为re.findall返回的是列表元组的形式,在后续的json文件写入时是列表列表的形式
        ips.append(list(ip))
        # print(ip)
    # ips = ip_list
    # global_ips = [ip for ip in ips if ip.startswith("10")]
    global_ips = [ip for ip in ips]
    whether_to_send, send_ip = get_temp_ip(global_ips)
    send_ip = json.dumps(send_ip)
    return whether_to_send, send_ip, cmd_result


if __name__ == "__main__":
    whether_to_send, global_ips, cmd_result = get_ip()
    if whether_to_send:
        send_an_email(global_ips, cmd_result)
    else:
        print("wait and no send")
        print(asctime())

都看到这儿了~ 有用的话~点个攒呗^- ^

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1009094.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号