linux定时任务和发送邮件
文章目录
- 定时任务
- cron
- 使用
- crontab格式与时间规则
- 用户级vs系统级crontab: 核心区别
- 普通用户使用
- 定时同步时间
- 定时备份 /etc/ 目录(脚本)
- 故障案例 PATH环境变量
- 发送邮件
- 环境准备
- 163邮箱发送给qq邮箱
- qq邮箱发送给163邮箱
- 配置表白脚本
- 定时巡检脚本发送邮件
- mailx与sendmail
- sendmail:底层邮件传输代理(MTA)
- mailx:命令行邮件客户端(MUA)
- 两种使用方式
- 配置文件
- 读取本地邮件
定时任务
cron
Linux 的 cron 是系统中自动执行定时任务的核心工具,可用于定期运行命令、脚本(如系统备份、日志清理、自动化报表等)。以下从基础到高级全面讲解其用法:
- 工作逻辑:
cron每分钟会检查「定时任务配置文件(crontab)」,若当前时间匹配任务的时间规则,就自动执行对应的命令 / 脚本。
组成部分:
- cron 守护进程:后台调度任务的核心服务。
- crontab 文件:存储定时任务的配置表(分用户级和系统级)。
- cron 日志:记录任务执行情况(通常在
/var/log/cron或/var/log/syslog)
使用
检查是否安装cron
rpm -qa | grep cron
检查是否运行,是否开机自启动
systemctl status cron
systemctl is-enabled cron
安装
yum install -y cron
1.编辑当前用户的定时任务
crontab -e
2.查看当前用户的任务
crontab -l
删除任务(谨慎使用)
crontab -r
crontab格式与时间规则
每个定时任务的格式为:* * * * * command_to_be_executed,其中前 5 个字段是「时间规则」,最后是「要执行的命令 / 脚本」。
| 字段顺序 | 含义 | 取值范围 | 特殊符号用法 |
|---|---|---|---|
| 第 1 个 | 分钟 | 0-59 | *(每分钟)、*/5(每 5 分钟)等 |
| 第 2 个 | 小时 | 0-23 | 同上 |
| 第 3 个 | 日 | 1-31 | 同上 |
| 第 4 个 | 月 | 1-12 | 同上 |
| 第 5 个 | 星期几 | 0-7(0/7 为周日) | 同上 |
特殊符号示例:
*:匹配 “所有可能值”,如* * * * *表示 “每分钟执行一次”。,:枚举值,如1,3,5 * * * *表示 “第 1、3、5 分钟执行”。-:范围值,如1-5 * * * *表示 “第 1 到 5 分钟执行”。/:步长,如*/10 * * * *表示 “每 10 分钟执行一次”。
示例
每天的上午7点到下午6点,每2个小时运行CMD命令
00 7-18/2 * * * CMD
半夜12点运行备份任务
00 00 * * * bash beifen.sh
用户级vs系统级crontab: 核心区别
| 维度 | 用户级 crontab(crontab -e) | 系统级 crontab(/etc/crontab 等) |
|---|---|---|
| 配置方式 | 普通用户可直接用 crontab -e 编辑 | 需 root 权限,手动编辑文件(如 nano /etc/crontab) |
| 格式差异 | 无 “用户” 字段(默认当前用户执行) | 多一个 “用户” 字段(指定任务执行的用户) |
| 示例 | 0 3 * * * /home/user/backup.sh | 0 3 * * * root /home/user/backup.sh |
| 存放路径 | /var/spool/cron/tabs/用户名 | /etc/crontab、/etc/cron.d/ 目录 |
| 适用场景 | 个人定时任务(如备份个人文件) | 系统级任务(如日志轮转、系统监控) |
普通用户使用
su - root
#在root用户修改文件
vim /etc/cron.allow
#在下面添加用户名
shf
#切换普通用户使用
su - shf
crontab -e
定时同步时间
1.测试命令
ntpdate ntp.aliyun.com
2.书写定时任务配置文件
crontab -e
#在下面添加以下内容并保存退出
#1.定时同步时间定时任务
#分 时 日 月 周
#每5分钟执行一次
*/5 * * * * /sbin/ntpdate ntp.aliyun.com >/dev/null 2>&1
3.定时任务修改完成,检查看日志,看结果
- /var/log/cron
tail -f /var/log/crondate
4.修改定时任务时间,改为正常时间
定时备份 /etc/ 目录(脚本)
脚本与测试
[root@kylin-v10-shf ~]#cat /server/scripts/check_tar.sh
------------------------------------------------------
#!/bin/bash
#author:夜
#说明:备份指定的目录#变量
back=backup-etc
time=$(date +%F_%w)
etc=etc-copy
log=log-copy
#命令
mkdir -p /${back}/{etc-copy,log-copy}
mkdir -p /tmp/{etc_bak,log_bak}
tar -zcf /${back}/${etc}/etc-${time}.tar.gz /etc/ 2>/dev/null
tar -zcf /${back}/${log}/log-${time}.tar.gz /var/log/ 2>/dev/null
find /backup-etc/ -type f -name *.tar.gz -mtime +7 | xargs rm -f
#查看压缩结果
echo "-----详细日志文件请您查看--------"
tree /${back}/
ls -l /${back}/${etc}
ls -l /${back}/${log}
----------------------------------------------------
定时任务
[root@kylin-v10-shf ~]#crontab -e
#添加以下内容
#2.定时备份任务
00 12 * * * bash /server/scripts/check_tar.sh >> /server/scripts/log/tar.log
查看日志,结果
#查看日志是否成功
[root@kylin-v10-shf ~]#tail -f /var/log/cron
Sep 19 17:41:01 kylin-v10-shf CROND[6433]: (root) CMD (bash /server/scripts/check_tar.sh >> /server/scripts/log/tar.log )
Sep 19 17:41:02 kylin-v10-shf CROND[6428]: (root) CMDEND (bash /server/scripts/check_tar.sh >> /server/scripts/log/tar.log )#查看etc备份
root@kylin-v10-shf ~]#ll /backup-etc/etc-copy/
总用量 5384
-rw-r--r-- 1 root root 5512552 9月 19 17:39 etc-2025-09-19_5.tar.gz
#查看日志备份
[root@kylin-v10-shf ~]#ll /backup-etc/log-copy/
总用量 1292
-rw-r--r-- 1 root root 1320812 9月 19 17:39 log-2025-09-19_5.tar.gz
故障案例 PATH环境变量
1.故意整点小故障
#写一个简单脚本
vim ss.sh
#添加以下内容
ss -lntup
#写到定时任务里
crontab -e
#添加以下内容
* * * * * bash /root/log/ss.sh > /root/log/ss.log
2.查看结果和日志
tail -f /var/log/cron
#显示有输出
Sep 19 19:52:01 kylin-v10-shf CROND[3433]: (root) CMDEND (bash /root/log/ss.sh >> /root/log/ss.log)
Sep 19 19:52:01 kylin-v10-shf CROND[3515]: (root) CMD (bash /root/log/ss.sh >> /root/log/ss.log)
#查看结果
cat /root/log/ss.log
#显示为空
3.解决方案
1.在脚本开头重新定义 export PATH=/usr/bin/:/usr/sbin/:/usr/local/bin/:/usr/local/sbin
2.source /etc/profilevim ss.sh
#在开头添加
source /etc/profile#查看日志和结果
cat ss.log
#有输出
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 127.0.0.1:323 0.0.0.0:* users:(("chronyd",pid=757,fd=6))
udp UNCONN 0 0 [::1]:323 [::]:* users:(("chronyd",pid=757,fd=7))
发送邮件
环境准备
- 麒麟/centos
安装mailx sendmail
yum install -y mailx sendmail
#网易邮箱
cat >>/etc/mail.rc<<EOF
#在最后面添加
set from=18045370844@163.com #默认发件人邮箱
set smtp=smtp.163.com #发送邮件的 SMTP 服务器地址
set smtp-auth-user=18045370844@163.com #SMTP 服务器的登录用户名
set smtp-auth-password=MJc3iW4KDECLpBf6 #SMTP 效验码
set smtp-auth=login #SMTP 认证方式(通常为login)
set charset=utf-8 #邮件默认编码
EOFecho 内容 | mailx -v -s 主题 1393845401@qq.com------------------------------------
#qq邮箱
cat >>/etc/mail.rc<<EOF
#在最后面添加
set bsdcompat
set -S DEAD=""
set from=1393845401@qq.com #默认发件人邮箱
set smtp=smtp.qq.com:587 #SMTP 服务器的登录用户名
set smtp-auth-user=1393845401@qq.com #SMTP 服务器的登录用户名
set smtp-auth-password=xvagfhgvlzxmhjfe #SMTP 效验码
set smtp-auth=login #邮件默认编码
set smtp-use-starttls=yes # 启用STARTTLS加密升级(关键)
set nss-config-dir=/etc/pki/nssdb/
EOF
测试发送
echo "测试STARTTLS" | mailx -v -s "587端口测试" 18045370844@163.com
可以查看交互日志
- ubuntu安装
apt install -y mutt
网易163邮箱
#配置文件
cat > ~/.muttrc << EOF
set from = "18045370844@163.com" # 发件人邮箱
set realname = "Ubuntu Server" # 发件人名称(可选)
set smtp_url = "smtps://18045370844@163.com@smtp.163.com:465/" # SMTP服务器(带加密)
set smtp_pass = "MJc3iW4KDECLpBf6" # 163邮箱授权码(非登录密码)
set ssl_verify_host = no # 忽略主机验证
set charset = "utf-8" # 解决中文乱码
EOF-----------------------------------------------
qq邮箱
cat > ~/.muttrc << EOF
set from = "1393845401@qq.com" # 发件人邮箱
set realname = "Ubuntu Server" # 发件人名称(可选)
set smtp_url = "smtps://1393845401@qq.com@smtp.qq.com:465/" # SMTP服务器(带加密)
set smtp_pass = "xvagfhgvlzxmhjfe" # 163邮箱授权码(非登录密码)
set ssl_verify_host = no # 忽略主机验证
set charset = "utf-8" # 解决中文乱码
Eecho "邮件内容" | mutt -s "邮件主题" 1393845401@qq.com
163邮箱发送给qq邮箱
准备两个邮箱
QQ邮箱:xxxxxx@qq.com
网易163邮箱:xxxxxxx@163.com
网易163邮箱配置
注册成功后

将POP3/SMTP服务开启


将效验码复制下来点确定

忘了效验码怎么办?

将设备删除,重新添加复制即可
在Linux服务器配置mail文件
配置文件 /etc/mail.rc
#在最后面添加
set from=18045370844@163.com #默认发件人邮箱
set smtp=smtp.163.com #发送邮件的 SMTP 服务器地址
set smtp-auth-user=18045370844@163.com #SMTP 服务器的登录用户名
set smtp-auth-password=MJc3iW4KDECLpBf6 #SMTP 效验码
set smtp-auth=login #SMTP 认证方式(通常为login)
set charset=utf-8 #邮件默认编码
发送邮件
mailx -s 主题 123456@qq.com 内容
echo 内容 | mailx -s 主题 1233457@qq.com
qq邮箱发送给163邮箱
注册成功后
将SMTP服务开启,点击设置

点击账号

鼠标滑到下面

开启服务,绑定手机号后,弹出效验码,复制即可

在Linux服务器配置mail配置文件
在/etc/mail.rc
vim /etc/mail.rc
#在最后面添加
set bsdcompat
set -S DEAD=""
set from=1393845401@qq.com #默认发件人邮箱
set smtp=smtp.qq.com:587 #SMTP 服务器的登录用户名
set smtp-auth-user=1393845401@qq.com #SMTP 服务器的登录用户名
set smtp-auth-password=xvagfhgvlzxmhjfe #SMTP 效验码
set smtp-auth=login #邮件默认编码
set smtp-use-starttls=yes # 启用STARTTLS加密升级(关键)
set nss-config-dir=/etc/pki/nssdb/测试发送
echo "测试STARTTLS" | mailx -v -s "587端口测试" 18045370844@163.com
可以查看交互日志
成功发送

误报

“message not sent” 误报的原因
mailx 之所以报错,是因为其内部判断 “发送成功” 的逻辑可能严格依赖特定的响应格式(例如期望服务器返回带具体队列 ID 的 250 OK queued as XXXXX),而 QQ 邮箱返回的 250 OK: queued as.(末尾带句号或缺少完整队列 ID)未被 mailx 正确识别,导致误判为 “发送失败”。
这种情况在 bsd-mailx 等旧版本 mailx 中较常见,因其对现代邮件服务器的响应兼容性较差。
解决方案
消除错误提示(可选)
echo "测试内容" | mailx -s "主题" 18045370844@163.com 2>/dev/null
升级mailx版本(彻底解决误报)
若希望从根本上消除误报,可安装对 SMTP 响应解析更完善的 heirloom-mailx 版本:
# 安装 heirloom-mailx(麒麟系统若支持 yum/dnf 源)
sudo yum install heirloom-mailx -y# 安装后验证版本(应显示 "Heirloom Mailx")
mailx -V# 重新测试,通常不会再误报
echo "测试升级后" | mailx -v -s "heirloom-mailx测试" 18045370844@163.com
配置表白脚本
调用一个API
天聚数行TianAPI - 应用开发者API数据调用平台
可以在这里用免费的
注册成功,点击接口





使用即可
配置表白脚本
vim mail.sh
----------------------------------------------------
#!/bin/bash
#vars
url=`curl -s -X POST -H "Content-Type:application/x-www-form-urlencoded" -d "key=865245c99f4fda69b6f05a53ef5a167c" "https://apis.tianapi.com/zhanan/index" | awk -F'content":"|"}}' '{print $2}'`
loves="18045370844@163.com 1393845401@qq.com"
echo "$url" | mailx -s "表白" $loves 2>/dev/null
-----------------------------------------------------
#测试一下
bash mail.sh
查看最新邮件是否发送
qq邮箱

163邮箱

定时巡检脚本发送邮件
vim mail.sh
------------------------------------------
bash /server/scripts/mail_sys.sh >/server/scripts/mail_sys.txt
emait="18045370844@163.com 1393845401@qq.com"
mailx -s "每日巡检" $emait < /server/scripts/mail_sys.txt 2>/dev/null
------------------------------------------
测试
bash mail.sh


成功发送
写入定时任务,先用每分钟测试
#写入定时任务
crontab -e
#4.每日巡检发送邮件
* * * * * bash /server/scripts/mail.sh
查看邮件


成功,重新改定时任务时间
crontab -e
#4.每日巡检发送邮件
00 22 * * * bash /server/scripts/mail.sh
mailx与sendmail
在 Linux 系统中,mailx 和 sendmail 是处理邮件发送的核心工具,但二者定位和功能差异显著:mailx 是交互式邮件客户端,提供用户友好的命令行界面用于编写、发送和读取邮件;sendmail 则是邮件传输代理(MTA),负责底层的邮件路由和投递,是 Linux 系统默认的邮件传输核心。下面将从工具定义、工作原理、使用方法、区别与联系等维度展开详细解释。
核心概念与定位
| 工具 | 类型 | 核心功能 | 用户交互性 | 依赖关系 |
|---|---|---|---|---|
mailx | 邮件用户代理(MUA) | 提供命令行界面,供用户编写、发送、接收、读取邮件,是 “用户与邮件系统的接口” | 强(交互式) | 依赖 MTA(如 sendmail)发送邮件 |
sendmail | 邮件传输代理(MTA) | 接收邮件(来自 MUA 或其他 MTA),解析收件人地址,通过 SMTP 路由到目标服务器 | 弱(后台服务) | 独立运行,可被 MUA / 脚本调用 |
sendmail:底层邮件传输代理(MTA)
sendmail 是 Unix/Linux 系统中历史最悠久、最经典的 MTA,负责邮件的 “传输” 而非 “编辑”,是邮件从本地发送到互联网的 “搬运工”。
- 核心作用与工作流程
sendmail 的核心是按照邮件地址规则投递邮件,其工作流程可概括为 4 步:
- 接收邮件:从本地
mailx、脚本(如echo "内容" | sendmail)或其他 MTA 接收待发送的邮件; - 解析地址:分析收件人邮箱(如
user@example.com),提取域名(example.com),通过 DNS 查询目标域名的 MX 记录(邮件交换服务器地址,如mx.example.com); - 建立连接:与目标 MX 服务器通过 SMTP 协议(25 端口,或加密的 465/587 端口) 建立连接;
- 投递邮件:将邮件内容传输到目标 MX 服务器,完成投递(后续由目标服务器分发到收件人邮箱)。
服务状态与端口
systemctl status sendmail
- 正常运行时,状态会显示
active (running),并监听 25 端口(可通过netstat -tuln | grep 25验证)。
mailx:命令行邮件客户端(MUA)
mailx 是 mail 命令的增强版,提供更友好的交互式界面,支持编写、发送、接收、读取邮件,本质是 “用户操作邮件的工具”,发送邮件时需依赖 sendmail 等 MTA。
- 核心作用
mailx 的核心是简化用户与邮件系统的交互,主要功能包括:
- 交互式编写邮件(支持输入主题、收件人、正文);
- 读取本地邮箱(默认
/var/spool/mail/用户名)中的邮件; - 转发、回复已接收的邮件;
- 发送带附件、抄送(CC)、密送(BCC)的邮件。
两种使用方式
1,交互式模式(适合手动编写邮件)
#进入mailx 交互式界面,指定收件人
mailx xxxxx@qq.com
#按提示输入主题(Subject),按 Enter 确认
Subject: 这是 mailx 测试邮件
# 3. 输入邮件正文(多行可直接输入)
这是通过 mailx 交互式发送的正文内容。
第二行内容。
# 4. 输入完成后,按 Ctrl+D 结束输入
2.非交互模式(适合脚本自动化)
通过管道(|)或重定向(<)传递邮件内容,无需手动输入,常用于脚本:
# 方式1:通过 echo 传递内容(-s 指定主题)
echo "这是非交互式发送的正文" | mailx -s "mailx 非交互式测试" test@example.com# 方式2:通过文件传递正文(将 file.txt 内容作为邮件正文)
mailx -s "邮件正文来自文件" test@example.com < /path/to/file.txt
配置文件
mailx 的配置文件分为 系统级 和 用户级,优先级:用户级配置 > 系统级配置(用户配置会覆盖系统配置)。
| 配置级别 | 路径 | 作用范围 |
|---|---|---|
| 系统级 | /etc/mail.rc 或 /etc/mailx.rc | 对所有系统用户生效 |
| 用户级 | ~/.mailrc 或 ~/.mailxrc | 仅对当前用户生效(推荐使用) |
核心配置项详解
mailx 的配置通过在配置文件中添加 set 配置项=值 实现,常用核心配置项如下:
| 配置项 | 作用说明 | 示例值 |
|---|---|---|
from | 默认发件人邮箱(格式:用户名@域名 或 昵称<用户名@域名>) | set from="张三<zhangsan@example.com>" |
smtp | 发送邮件的 SMTP 服务器地址(含端口,常用端口:25 无加密,465 SSL,587 STARTTLS) | set smtp="smtp.example.com:587" |
smtp-auth | SMTP 认证方式(通常为 login,部分服务器支持 plain) | set smtp-auth=login |
smtp-auth-user | SMTP 服务器的登录用户名(通常是发件人邮箱全称) | set smtp-auth-user=zhangsan@example.com |
smtp-auth-password | SMTP 服务器的登录密码(注意:部分邮箱需用 “应用专用密码”,如 Gmail、QQ 邮箱) | set smtp-auth-password="your-password" |
smtp-use-starttls | 启用 STARTTLS 加密(连接到 587 端口时常用) | set smtp-use-starttls=yes |
nss-config-dir | 证书目录(用于 SSL 加密验证,避免 “证书不信任” 错误) | set nss-config-dir=/etc/pki/nssdb/ |
charset | 邮件默认编码(避免中文乱码,推荐 utf-8) | set charset=utf-8 |
signature | 邮件签名文件路径(自动添加到邮件末尾) | set signature=~/.mail_signature |
读取本地邮件
inux 系统默认将本地用户的邮件存储在 /var/spool/mail/用户名(如 root 用户的邮件在 /var/spool/mail/root),mailx 可直接读取:
# 1. 读取当前用户的所有本地邮件
mailx# 2. 界面会显示邮件列表(如 “1 from test@example.com Wed Oct 11 10:00”)
# 输入邮件编号(如 1)查看该邮件内容
# 输入 h 查看邮件列表,输入 d 1 删除第1封邮件,输入 q 退出
