Я сделал это. Я создаю новый файл (с суффиксом at «.new»), но перед заменой старого я проверяю разницу в размерах файлов и прерываю (отправляя какое-либо уведомление, например по почте), если изменений слишком много.
Я обычно делаю это на perl, но bash будет похож.
$file="file_being_updated";
$new=".new";
if ( -f $file ) {
my $percent_diff = abs( 100 - 100*(-s "$file$new")/(-s $file) );
if ( $percent_diff > 20 ) { # more that this to different!
printf STDERR "File \"$file$new\" differs by more that 20%%! (%.1f%%)\n", $percent_diff;
printf STDERR "-------------- ABORTING REPLACMENT -----------\n";
exit 10;
}
}
Я бы порекомендовал что-то более похожее на следующее:
sed -i 's|$DEFAULT_MAIL_DOMAIN = \"padl.com\";|$DEFAULT_MAIL_DOMAIN = \"$E_DOMAIN\";|' /usr/share/migrationtools/migrate_common.ph
Изменения, которые я сделал:
/
на |
для синтаксиса подстановки sed. Эта часть не нужна. Я просто предпочитаю это. Вы можете оставить /
, если хотите. Если $DEFAULT_MAIL_DOMAIN
и кавычки являются буквальной частью файла,
нам нужно использовать одинарные кавычки или обратную косую черту, чтобы избежать их. Итак, одно из следующего:
$ E_DOMAIN=foobar.com
$ sed -e 's/$DEFAULT_MAIL_DOMAIN = "padl.com"/$DEFAULT_MAIL_DOMAIN = "'"$E_DOMAIN"'"/' file
# Default DNS domain
$DEFAULT_MAIL_DOMAIN = "foobar.com";
...
$ sed -e "s/\$DEFAULT_MAIL_DOMAIN = \"padl.com\"/\$DEFAULT_MAIL_DOMAIN = \"$E_DOMAIN\"/" file
# Default DNS domain
$DEFAULT_MAIL_DOMAIN = "foobar.com";
В первом случае кавычки интерпретируются следующим образом:
'.../$DEFAULT_MAIL_DOMAIN = "'"$E_DOMAIN"'"/'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ - single-quoted, literal ""s
^^^^^^^^^^^ - double-quoted, var expanded
Во втором все это представляет собой строку в двойных кавычках с проблемными $
и "
экранировано. Но не $
в $E_DOMAIN
, так как мы хотим расширить эту переменную.
Я не уверен, что переменная должна быть E_DOMAIN
или E_DOMAIN_VAR
, вы добавили суффикс .com
к последнему, но использовали первый в команде sed
. В любом случае, /
, &
или новая строка в переменной будут специально обработаны sed
, но доменное имя не должно их содержать
. цитирование немного смещено:
sed -i "s/"$DEFAULT_MAIL_DOMAIN = "padl.com";"/"$DEFAULT_MAIL_DOMAIN = "$E_DOMAIN";"/g"
Первая часть "s/"
является строкой в кавычках, затем $DEFAULT_MAIL_DOMAIN
находится вне кавычек, поэтому раскрывается как переменная (вероятно, до пустой строка). Пробелы также не заключены в кавычки, поэтому sed
получает несколько аргументов, и, вероятно, будет жаловаться. "padl.com"
снова заключен в кавычки, но точка с запятой отсутствует, поэтому оболочка интерпретирует ее как завершение команды.