#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 в двух процессах, вызывающих скрипт! Мне нравится эта идея!