Я пытался получить значение и замену подпрограммы perl, чтобы получить необходимую часть строки из подпрограммы randomips в exim.conf. Однако, когда я использую подстановку строк, я получаю сообщение об ошибке следующим образом:

Вот чего я пытаюсь добиться

Я пытаюсь разделить строку по двоеточию и получить первое вхождение как «интерфейс». Я буду использовать второе вхождение как "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'". Вероятно, синтаксис. Любая помощь?

0
Motsim 28 Май 2017 в 12:33

2 ответа

Лучший ответ

Код, который вы пытаетесь скопировать, был написан кем-то, кто мало знает о Perl. Включает в себя эту строку:

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

Программист Perl написал бы это как

return $inet[rand @inet];

Я думаю, что здесь есть пара проблем - одна с вашим синтаксисом exim, а другая с вашим синтаксисом Perl.

Exim дает вам эту ошибку:

не удалось развернуть опцию «interface» для транспорта dkim_remote_smtp: отсутствует «}» после «perl»

Я ничего не знаю о вызове Perl из Exim, но на этой странице упоминается такой синтаксис, как ${perl{foo}} (который аналогичен синтаксису, используемому на странице, с которой вы копируете), и такой, как ${perl{foo}{argument}}, для вызова подпрограммы и передачи ей аргумент . Нигде не упоминается такой синтаксис, как у вас:

${perl{randomhosts}%:*}

Я не уверен, откуда у вас этот синтаксис, но, похоже, именно это и стало причиной вашей первой ошибки.

В комментарии вы говорите

Я настаиваю, чтобы получить первую часть строки перед двоеточием для каждого случайного значения массива для «интерфейса» и часть после двоеточия для «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 / host, если его первым аргументом является «generate». Затем он вернет либо имя хоста, либо IP-адрес из сгенерированной пары. Я думаю, что вы, вероятно, можете вызвать его из вашего конфигурационного файла exim следующим образом:

dkim_remote_smtp:
  driver = smtp
  interface = "${perl{randomhosts}{generate}{ip}}"
  helo_data = "${perl{randomhosts}{host}}"

Но я не эксперт в exim, так что синтаксис может потребоваться настроить.

3
Dave Cross 28 Май 2017 в 16:20

Во-первых, я хотел бы отметить, что я не работал с exim, поэтому я не могу сказать, что именно вы пытаетесь сделать и почему вы сделали именно так.

В размещенной вами ссылке в exim.pl добавляется метод randinet, а строка интерфейса в exim.conf заменяется на

interface = "${perl{randinet}}"

Вы реализовали метод randomhosts и заменили строку интерфейса на

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

Теперь парсер жалуется на отсутствие закрывающей скобки. Вероятно, это связано с символами, которые вы можете добавить, но синтаксический анализатор не может игнорировать их.

Я предлагаю вам попробовать

interface = "${perl{randomhosts}}"

1
bytepusher 28 Май 2017 в 10:44