为何通过systemd运行时mutt无法发送邮件?
公网IP检测脚本在systemd下无法发送邮件问题
我编写了一个bash脚本,用于检测家庭网络的公网IP是否发生变化,若IP变化则通过mutt向个人邮箱发送包含新IP的通知邮件。脚本在命令行(CLI)下运行完全正常,但通过systemd托管运行时,虽能正常检测并对比IP,却无法发送邮件,且服务状态无报错信息。
脚本内容(CHECKIP)
第11-15行已注释用于排查问题,第16行为简化版发送逻辑:
#!/bin/bash last_ip=$(curl -s ifconfig.me) echo -e "Actual IP is: $last_ip\n" while [[ true ]];do actual_ip=$(curl -s ifconfig.me) if [ $actual_ip != $last_ip ]; then last_ip=$actual_ip echo -e "IP has changed. The new IP adress is: $actual_ip\n" #template=$(cat /home/karol/Projekty/bash-script/checkip-msg.html) #message=$(sed "s/{{actual_ip}}/$actual_ip/g" <<< $template) #tmp_msg="home/karol/Projekty/bash-script/tmp/email.html" #echo $message > $tmp_msg #mutt -s "IP chas changed" me -e "set content_type=text/html" < "$tmp_msg" mutt -s "IP has changed" me <<< "Your new IP address is $actual_ip" fi sleep 10 done
Systemd服务文件(/etc/systemd/system/checkip.service)
[Unit] Description=External IP checker After=network.target [Service] ExecStart=/bin/bash -lc "/home/karol/Projekty/bash-script/checkip.sh" [Install] WantedBy=network.target
服务启动时的status输出
karol@karol-P5K-E /etc/systemd/system$ service checkip status ● checkip.service - External IP checker Loaded: loaded (/etc/systemd/system/checkip.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2023-07-10 09:11:08 CEST; 11s ago Main PID: 28982 (checkip.sh) Tasks: 2 (limit: 4537) Memory: 860.0K CPU: 63ms CGroup: /system.slice/checkip.service ├─28982 /bin/bash /home/karol/Projekty/bash-script/checkip.sh └─29009 sleep 10 lip 10 09:11:08 karol-P5K-E systemd[1]: Started External IP checker. lip 10 09:11:09 karol-P5K-E bash[28982]: Actual IP is: X.XX.XX.XXX
IP变化时的status输出
karol@karol-P5K-E service checkip status ● checkip.service - External IP checker Loaded: loaded (/etc/systemd/system/checkip.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2023-07-10 09:11:08 CEST; 1min 31s ago Main PID: 28982 (checkip.sh) Tasks: 2 (limit: 4537) Memory: 1.2M CPU: 185ms CGroup: /system.slice/checkip.service ├─28982 /bin/bash /home/karol/Projekty/bash-script/checkip.sh └─29117 sleep 10 lip 10 09:11:08 karol-P5K-E systemd[1]: Started External IP checker. lip 10 09:11:09 karol-P5K-E bash[28982]: Actual IP is: X.XX.XX.XXX lip 10 09:12:20 karol-P5K-E bash[28982]: /home/karol/Projekty/bash-script/checkip.sh: line 8: [: !=: unary operator expected lip 10 09:12:31 karol-P5K-E bash[28982]: IP has changed. The new IP adress is: Y.YY.YY.YYY
问题分析与解决方法
1. Mutt配置与运行身份问题
命令行下mutt会加载当前用户的~/.muttrc配置,但systemd默认以root身份运行服务,无法读取你的用户配置,导致邮件发送失败。
- 解决:
- 在service文件的
[Service]段添加User=karol,让服务以你的用户身份运行:[Service] User=karol ExecStart=/home/karol/Projekty/bash-script/checkip.sh - 或者在脚本中指定mutt的配置文件路径:
mutt -F /home/karol/.muttrc -s "IP has changed" me <<< "Your new IP address is $actual_ip"
- 在service文件的
2. 变量空值导致的语法错误
从IP变化时的日志能看到line 8: [: !=: unary operator expected,这是因为$actual_ip或$last_ip为空,导致判断语句语法错误。
- 解决:
- 修改判断语句,用双引号包裹变量:
if [[ "$actual_ip" != "$last_ip" ]]; then - 处理curl请求失败的情况,避免变量为空:
actual_ip=$(curl -s ifconfig.me || echo "IP_CHECK_FAILED")
- 修改判断语句,用双引号包裹变量:
3. Systemd环境变量缺失
systemd服务的环境变量与命令行不同,可能缺少mutt所需的PATH或其他环境变量。
- 解决:在service文件的
[Service]段添加环境变量配置:[Service] Environment=PATH=/usr/bin:/bin:/usr/local/bin User=karol ExecStart=/home/karol/Projekty/bash-script/checkip.sh
4. 查看详细日志定位问题
服务状态无报错,但可以通过systemd日志查看mutt执行时的具体错误:
journalctl -u checkip.service -f
实时日志会显示邮件发送过程中的细节,比如认证失败、连接超时等。
内容的提问来源于stack exchange,提问作者Karol Pauk
相关产品推荐
相关产品推荐

