Программист исправил ошибку в генерации конфигов из предыдущей задачи.
Кроме того, он улучшил бекап старых конфигов:
теперь предыдущие версии будут попадать последовательно
в файлы app.conf.bak.1
, app.conf.bak.2
и т.п.
Удобно? Да, но есть одна особенность…
#!/usr/bin/perl
use strict;
use warnings;
use File::Slurp;
use IO::Prompt;
my $conf_file = "./app.conf";
my $new_conf = generate_conf();
if (-e $conf_file && prompt(-yn, "backup old conf? [yn]" )){
backup_old_conf();
}
write_file($conf_file, {}, $new_conf);
exit;
sub generate_conf
{
my $conf = '';
#...
return $conf;
}
sub backup_old_conf
{
my $i = 0;
# бекапим старые версии в файлах .bak.1, .bak.2 и т.д.
# проверяем, какие файлы уже существуют...
while(-e $conf_file.".bak.".$i++ ){
}
# ... и создаем файл с следующим номером
rename($conf_file, $conf_file.".bak.".$i) or die "can't backup old conf";
}
Новый конфиг генерится, предложение забекапить старый конфиг появляется и обрабатывается.
Вот только старых версий хранится слишком малое количество.
Прямо скажем: ровно одна старая версия сохраняется в app.conf.bak.1
,
при следующих запусках перезаписывается этот же файл,
а app.conf.bak.2
никогда не появляется.
Проблема классическая, C-подобная, и
происходит из-за постфиксного инкремента ($i++
) вот в этом цикле:
while(-e $conf_file.".bak.".$i++ ){ }
Сначала проверяется существование файла с номером из текущего значения $i
,
потом $i
увеличивается на единицу, и с таким номером
записывается файл в строке
rename($conf_file, $conf_file.".bak.".$i) or die "can't backup old conf";
Первый бекап происходит так: проверяем наличие файла с номером 0, его нет, записываем файл с номером 1. То же самое происходит и при создании всех следующих резервных копий.
Чтобы исправить ошибку, стоило бы использовать префиксный инкремент:
while(-e $conf_file.".bak.".++$i ){
}
rename($conf_file, $conf_file.".bak.".$i) or die "can't backup old conf";
Или же не пожалеть лишней строчки кода и написать совсем явно:
$i++;
while(-e $conf_file.".bak.".$i ){
}
rename($conf_file, $conf_file.".bak.".$i) or die "can't backup old conf";