У нас есть несколько серверов Linux Ubuntu 20-22, CentOS 7/RedHat 8, все они находятся в неправильном часовом поясе. Мне поставлена задача синхронизировать время на всех из них.
Я пробовал много вариантов, sed, awk, grep. «awk» был самым запутанным и недружелюбным. «sed» позволил мне заменить существующие записи, но я не могу реализовать его в цикле for, который будет проверять правильность записей, а затем выходить, если нет, то заменять их все.
Я боролся с этим последние 2 недели, потому что я новичок в программировании Bash.
Итак, я пытаюсь создать общий скрипт для всех них, чтобы заменить записи в chrony.conf
Например, в Ubuntu у chrony.conf
есть следующие записи:
# pool ntp.ubuntu.com iburst maxsources 4
# pool 0.ubuntu.pool.ntp.org iburst maxsources 1
В CentOS 7 chrony.conf
есть следующие записи
# server 0.centos.pool.ntp.org iburst
# server 1.centos.pool.ntp.org iburst
Если скрипт встречает указанные выше записи, он должен заменить их на записи ниже:
pool time.nrc.ca iburst
pool time.chu.nrc.ca iburst
Любая помощь / руководство приветствуется.
Если в файлах может быть несколько строк для замены одной, разбейте задачу на две: 1) удалите ненужные строки (или закомментируйте их); 2) добавить нужную строку. Но серверы NTP работают с UTC, как это связано с часовыми поясами? Вероятно, вам нужно настроить правильный часовой пояс, а не серверы NTP.
Почему вам нужно сначала проверить, все ли записи верны? Просто продолжайте использовать свой подход sed
или awk
и предположите, что они неверны. В этом случае ваш инструмент просто не найдет строку для замены, и после этого уже правильный файл останется неизменным. Возможно, единственным недостатком будет то, что временная метка файла была изменена; но вы видите в этом проблему?
Что касается "awk" has been the most confusing, and not friendly
- awk в основном представляет собой просто крошечное подмножество C
внутри неявного цикла while read line
, это только сбивает с толку и недружественно, если вы сначала не заглянете на справочную страницу, чтобы понять это, и попытаетесь использовать его, как если бы это было C
или подобное. Это намного яснее и проще, чем sed
для чего-то большего, чем s/old/new/
.
Я попробовал справочную страницу для awk, это не так просто, возможно, это проще для вас, поскольку вы, возможно, некоторое время писали сценарии, для начинающих это все еще сбивает с толку. Большинство ответов я получил, читая форумы.
@ user1934428 , Причина, по которой я должен проверить правильность существующих данных, заключается в том, что подготовленный мной сценарий развернут в политике Azure, поэтому Azure развертывает сценарий на всех виртуальных машинах Linux, и именно там сценарий проверяет правильность времени, а затем завершает работу. , если нет, то замените его новым временем.
Для явной проверки я бы все же сначала сделал замену на какой-то временный выходной файл. После этого я бы сравнил этот выходной файл с исходным файлом. Если отличий нет, ничего не нужно было заменять и временный файл можно просто удалить. Если есть различия, переместите временный файл поверх исходного файла.
Спасибо за эту идею, именно это сейчас и делает мой скрипт.
Ваши требования неясны в нескольких областях, например. что делать, если присутствует только одна из целевых строк, что делать, если целевой текст отображается в середине строки, что делать, если ни одной строки нет, что делать, если целевой текст и замещающий текст уже присутствуют, где чтобы поместить замещающий текст и т. д., так что вот одно предположение о том, что вы можете захотеть, используя любой POSIX awk:
$ cat tst.sh
#!/usr/bin/env bash
awk '
{
despaced = $0
gsub(/[[:space:]]+/," ",despaced)
}
( despaced == "# pool ntp.ubuntu.com iburst maxsources 4" ) ||
( despaced == "# pool 0.ubuntu.pool.ntp.org iburst maxsources 1" ) {
$0 = "pool time.nrc.ca iburst"
}
( despaced == "# server 0.centos.pool.ntp.org iburst" ) ||
( despaced == "# server 1.centos.pool.ntp.org iburst" ) {
$0 = "pool time.chu.nrc.ca iburst"
}
{ print }
' "${@:--}"
$ head ubuntu_chrony.conf cent_chrony.conf
==> ubuntu_chrony.conf <==
# pool ntp.ubuntu.com iburst maxsources 4
# pool 0.ubuntu.pool.ntp.org iburst maxsources 1
==> cent_chrony.conf <==
# server 0.centos.pool.ntp.org iburst
# server 1.centos.pool.ntp.org iburst
$ ./tst.sh ubuntu_chrony.conf
pool time.nrc.ca iburst
pool time.nrc.ca iburst
$ ./tst.sh cent_chrony.conf
pool time.chu.nrc.ca iburst
pool time.chu.nrc.ca iburst
Спасибо, что изучили это @Ed Morton, я решил это с помощью другого подхода, используя комбинацию awk, sed и цикла for. если целевые строки присутствуют, мне нужно проверить их правильность, прежде чем удалять или заменять их. Сценарий, который я подготовил, развертывается в политике Azure, поэтому Azure развертывает сценарий, и именно там сценарий проверит правильность времени, затем завершит работу, если нет, то заменит его новым часовым поясом.
На мой взгляд, если записи в
chrony.conf
такие, как показано, то есть если они начинаются с#
, то их не нужно удалять. Просто добавьте свою строкуpool time.nrc.ca iburst
иpool time.chu.nrc.ca iburst
вchrony.conf
, используяecho "pool time.chu.nrc.ca iburst" >> /etc/chrony.conf
иecho "pool time.nrc.ca iburst" >> /etc/chrony.conf