您试图复制的代码是由不太了解 Perl 的人编写的。它包括这一行:
return $inet[int rand($#inet+1)];
Perl 程序员会这样写
return $inet[rand @inet];
我认为这里有几个问题 - 一个与您的 Exim 语法有关,另一个与您的 Perl 语法有关。
Exim 给你这个错误:
无法扩展 dkim_remote_smtp 传输的“接口”选项:在“perl”之后缺少“}”
我对从 Exim 调用 Perl 一无所知,但是这个页面提到了一种语法${perl{foo}}
(类似于您要从中复制的页面中使用的语法),以及一种${perl{foo}{argument}}
用于调用子例程并向其传递参数的语法。它没有提到像你这样的语法:
${perl{randomhosts}%:*}
我不确定您从哪里获得该语法,但似乎这可能是导致您的第一个错误的原因。
在评论中,你说
我正在为“interface”的每个随机数组值获取冒号之前的字符串的第一部分,为“helo_data”获取冒号之后的部分
在我看来,Exim 似乎不支持这个要求。您需要调用该函数两次才能获得所需的两条信息。您也许可以在 Perl 中使用state
变量之类的东西来做到这一点 - 但它会比您当前拥有的代码复杂得多。
其次,您的 Perl 代码有语法错误,因此即使 Exim 能够调用您的代码,它也无法正常工作。
您正在复制的代码设置@inet
如下:
@inet = ("x.x.x.1", "x.x.x.2", "x.x.x.3", "x.x.x.4");
您的等效代码是这样的:
@inet = (
"x.x.x.1:hostname1.domain.com",
"x.x.x.2:hostname2.domain.com,
x.x.x.3:hostname3.domain.com
);
我已经对其进行了重新格式化,以使问题更加明显。您在数组元素周围缺少许多引号。(注意:我看到虽然我一直在写这个答案,但你已经解决了这个问题。)
更新:好的,这里有一些代码可以满足exim.pl
您的需求。
use feature qw[state];
sub randomhosts {
state $current;
my @inet = (
"x.x.x.1:hostname1.domain.com",
"x.x.x.2:hostname2.domain.com",
"x.x.x.3:hostname3.domain.com"
);
if ($_[0] eq 'generate') {
shift;
@{$current}{qw[ip host]} = split /:/, $inet[rand @inet];
}
return $current->{$_[0]};
}
如果它的第一个参数是“生成”,它会生成一个新的 ip/主机对。然后它将从生成的对中返回主机名或 IP 地址。我认为您可以像这样从您的 Exim 配置文件中调用它:
dkim_remote_smtp:
driver = smtp
interface = "${perl{randomhosts}{generate}{ip}}"
helo_data = "${perl{randomhosts}{host}}"
但我不是 Exim 方面的专家,因此可能需要调整语法。