Когда подходящее время (и неправильное время) использовать обратные пометки - PullRequest
14 голосов
/ 22 сентября 2008

Многие начинающие программисты пишут такой код:

sub copy_file ($$) {
  my $from = shift;
  my $to = shift;

  `cp $from $to`;
}

Это плохо и почему? Должны ли когда-либо использоваться backticks? Если да, то как?

Ответы [ 14 ]

1 голос
/ 22 сентября 2008

Обратные метки должны использоваться только тогда, когда вы хотите захватить вывод. Использование их здесь «выглядит глупо». Любой, кто смотрит на ваш код, поймет, что вы не очень знакомы с Perl.

Используйте обратные пометки, если вы хотите захватить вывод. Используйте систему, если вы хотите выполнить команду. Одно из преимуществ, которое вы получите, - возможность проверить статус возврата. По возможности используйте модули для мобильности. В этом случае File :: Copy соответствует требованиям.

1 голос
/ 22 сентября 2008

Ваш пример плохой, потому что есть встроенные в Perl встроенные функции, которые являются переносимыми и, как правило, более эффективными, чем альтернатива backtick.

Их следует использовать только тогда, когда нет альтернативы встроенному Perl (или модулю). Это касается как обратных вызовов, так и системных вызовов. Обратные метки предназначены для захвата вывода выполненной команды.

0 голосов
/ 23 сентября 2008

Бэктикс для любителей. Пуленепробиваемым решением является «Safe Pipe Open» (см. «Man perlipc»). Вы выполняете свою команду в другом процессе, который позволяет вам сначала выполнить STDERR, setuid и т. Д. Преимущества: не полагается на оболочку для анализа @ARGV в отличие от open ("$ cmd $ args | "), что ненадежно. Вы можете перенаправить STDERR и изменить права доступа пользователя, не изменяя поведение вашей основной программы. Это более многословно, чем обратные пометки, но вы можете обернуть его в свою собственную функцию, например, run_cmd ($ cmd, @ args);


sub run_cmd {
  my $cmd = shift @_;
  my @args = @_;

  my $fh; # file handle
  my $pid = open($fh, '-|');
  defined($pid) or die "Could not fork";
  if ($pid == 0) {
    open STDERR, '>/dev/null';
    # setuid() if necessary
    exec ($cmd, @args) or exit 1;
  }
  wait; # may want to time out here?
  if ($? >> 8) { die "Error running $cmd: [$?]"; }
  while (<$fh>) {
    # Have fun with the output of $cmd
  }
  close $fh;
}
0 голосов
/ 23 сентября 2008

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

При использовании языка программирования следует избегать обратных кавычек. Это отсутствие ошибки проверка и, если можно избежать выполнения отдельных обратных программ, эффективность получил.

Помимо вышесказанного, системная функция должна использоваться, когда вывод команды не используется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...