You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何通过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"
      

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 22:54:51