Могу ли я использовать блокировку файлов в этом сценарии?

#perl #filelock

Вопрос:

Пожалуйста, у меня есть концептуальный вопрос. У меня есть два процесса, которые выводят файл с одинаковым именем в одном каталоге, а затем выполняют/читают этот файл в скрипте perl. Эти два процесса могут выполняться одновременно, и я боюсь, что есть вероятность, что файл может быть перезаписан другим процессом, следовательно, один из процессов выполняет неправильный исходный файл. по сути, строка выглядит следующим образом : (две строки являются общими для обоих процессов)

 $cmd = `my_script.pl`;  ## This generates runx file
$cmd = `source runx | grep - i "Error";`
 

ПРИМЕЧАНИЕ: У меня нет контроля над именем файла, и я должен запускать оба процесса в одном и том же

Могу ли я использовать эксклюзивную блокировку файлов сразу после первой команды, чтобы предотвратить сговор?

Ответ №1:

Файл, который вы блокируете, не обязательно должен быть файлом, который вы хотите защитить.

 use Fcntl qw( LOCK_EX );

my $output;
{
   my $script_qfn = 'my_script.pl';
   my $lock_qfn  = $script_qfn . '.lock';

   open(my $fh, '>', $lock_qfn)
      or die("Can't create lock file "$lock_qfn": $!n");

   flock($fh, LOCK_EX)
      or die("Can't lock "$lock_qfn": $!n");

   system { $script_qfn } $script_qfn;
   $output = `source runx | grep -i Error`;
}
 

Но почему бы не my_script.pl отправить его вывод в STDOUT? Тогда не было бы необходимости запираться. Вы могли бы просто использовать следующее:

 my $output = `my_script.pl | sh | grep -i Error`;
 

Есть три способа позвонить system :

  • system($shell_command) .
  • system($prog, @args) . Должен быть хотя бы один аргумент.
  • system({ $prog } $arg0, @args) . 0 аргументов.

В этом случае у нас не было команды оболочки, и у нас не было никаких аргументов, поэтому нам пришлось использовать третий подход (или создать команду оболочки, скажем, с помощью строки::ShellQuote shell_quote ). Для использования system($script_qfn) была бы введена ошибка внедрения кода.

Комментарии:

1. Могу я спросить, почему у вас тело кода в { } ? Это просто для ясности? Я также могу попробовать ваше другое предложение.

2. Ответ добавлен в нижнюю часть поста. system($script_qfn) это привело бы к ошибке с внедрением кода .

3. Большое спасибо! Это действительно потрясающе-знать, что я могу просто заблокировать скрипт perl в двух процессах, вызывающих скрипт! Мне нравится эта идея!