0

我一直在尝试获取 perl 子例程值和替换,以从 exim.conf 中的 randomips 子例程中获取所需的字符串部分。但是,当我使用字符串替换时,我得到如下错误:

这是我想要实现的目标

我正在尝试用冒号拆分字符串并将第一次出现作为“接口”。我将使用第二次出现作为“helo_data.

exim.pl

sub randomhosts {
@inet = ("x.x.x.1:hostname1.domain.com","x.x.x.2:hostname2.domain.com","x.x.x.3:hostname3.domain.com"
);

return $inet[int rand($#inet+1)];

}

exim.conf

dkim_remote_smtp:
  driver = smtp
  interface = "${perl{randomhosts}%:*}"
  helo_data = "${sender_address_domain}"

我得到的错误如下:

"failed to expand "interface" option for dkim_remote_smtp transport: missing '}' after 'perl'". 大概是语法。有什么帮助吗?

4

2 回答 2

3

您试图复制的代码是由不太了解 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 方面的专家,因此可能需要调整语法。

于 2017-05-28T11:15:43.090 回答
1

首先,我想指出我没有与 exim 合作过,所以我不能说你到底想做什么以及为什么你会这样做。

在您发布的链接中,将一个名为“randinet”的方法添加到 exim.pl,并将 exim.conf 中的接口行替换为

interface = "${perl{randinet}}"

您已经实现了一个 'randomhosts' 方法并将接口行替换为

interface = "${perl{randomhosts}%:*}"

现在解析器抱怨找不到右括号。这可能是由于您可以随意添加符号,但解析器没有忽略的自由。

我建议你试试

interface = "${perl{randomhosts}}"

于 2017-05-28T10:44:11.917 回答