Mutt邮件客户端banmail脚本报错求助:引号匹配与EOF问题
脚本语法错误排查与修复
你遇到的unexpected EOF错误,根源是脚本里的引号、命令替换语法不匹配,还有几处细节语法错误,逐一修正如下:
1. 提取邮箱的命令行语法错误
原脚本第一行:
mail="$(grep "^From:" /dev/stdin | grep -o "[^<> ]\+@.\+\\.[^<>]\+"]" && break
存在3个问题:
- 命令替换
$(...)未闭合,缺少右括号) - 正则表达式末尾多了一个多余的
] - 多余的
&& break破坏语法结构,完全没必要
修正后:
mail="$(grep "^From:" /dev/stdin | grep -o "[^<> ]\+@.\+\.[^<>]\+")"
2. if条件判断的空格缺失
原脚本:
if [-n "$1" ]; then
[是shell的测试命令,必须和后续参数之间加空格,否则会被当作不存在的命令,修正为:
if [ -n "$1" ]; then
3. 变量赋值的语法错误
原脚本:
domain=$"(echo $mail | cut -d@ -f2)"
$"是错误写法,正确的命令替换语法是$(...);同时为避免空格等特殊字符问题,$mail要加双引号,修正为:
domain="$(echo "$mail" | cut -d@ -f2)"
4. 额外优化:规避eval的安全风险
原脚本用eval执行ssh命令,存在安全隐患(若邮箱/域名含特殊字符会被shell错误解析),可直接用ssh传递命令,同时把变量用单引号包裹,防止本地shell提前替换:
将原代码:
eval "ssh root@www.rebootcyber.xyz 'echo blacklist_from $domain >> /etc/spamassassin/local.cf;systemctl reload spamassassin &'"
改为:
ssh root@www.rebootcyber.xyz "echo 'blacklist_from $domain' >> /etc/spamassassin/local.cf; systemctl reload spamassassin"
(去掉后台&,避免ssh提前断开导致远程命令未执行完成)
修正后的完整脚本
#!/bin/sh mail="$(grep "^From:" /dev/stdin | grep -o "[^<> ]\+@.\+\.[^<>]\+")" # Give an argument to this command to ban ALL address from this domain if [ -n "$1" ]; then domain="$(echo "$mail" | cut -d@ -f2)" read -r choice </dev/tty echo "$choice" | grep -i "^y$" && ssh root@www.rebootcyber.xyz "echo 'blacklist_from $domain' >> /etc/spamassassin/local.cf; systemctl reload spamassassin" else echo "Ban only mail address" echo "Really ban $mail? [y/N]" read -r choice </dev/tty echo "$choice" | grep -i "^y$" && ssh root@www.rebootcyber.xyz "echo 'blacklist_from $mail' >> /etc/spamassassin/local.cf; systemctl reload spamassassin" fi
补充说明
- 当前提取邮箱的正则可处理
From: John Doe <john@example.com>这类格式,能正确提取john@example.com - 执行脚本前需确保本地用户能免密ssh登录远程服务器root账号,否则会提示输入密码
- 需保证远程服务器的
/etc/spamassassin/local.cf文件允许root写入
内容的提问来源于stack exchange,提问作者darrion_tr1989
相关产品推荐
相关产品推荐

