«Идемпотентность» — это свойство, которое часто приписывают системам управления конфигурацией, одним из примеров которых является Ansible. Puppet также описывает себя как идемпотент; как и Ansible, правильнее было бы сказать «квази -идемпотентный», потому что оба они предлагают способы нарушения строгой идемпотентности.
Я думаю, что ваш вопрос частично мотивирован непониманием более формального значения идемпотентности, которая является операцией, которая всегда будет давать один и тот же результат, независимо от того, сколько раз вы ее применяете.
Хотя прибавление нуля или умножение на единицу удовлетворяют определению идемпотентности, мы можем назвать их тривиально идемпотентными. Они не -ops, и вообще идемпотентность не обязательно должна быть no -ops.
Некоторые примеры, которые могут помочь вам получить более общее представление об идемпотентности:
Последние два примера наиболее точно показывают, что подразумевается под идемпотентностью в контексте систем управления конфигурацией. В простейшем случае речь идет о переводе удаленной машины в желаемое состояние путем копирования файлов или выдачи команд. Как только пульт находится в этом состоянии, он не должен/не будет иметь эффекта для копирования файлов или повторного выполнения команд.
Причина, по которой идемпотентность позиционируется как желательное свойство систем управления конфигурацией, таких как Ansible или Puppet, заключается в том, что при управлении большим количеством серверов наиболее удобно, если как можно больше из них имеют одинаковую конфигурацию. Чтобы обеспечить единообразие, вы копируете нужные файлы конфигурации, настраиваете их брандмауэры одинаково и т. д. Но желательно иметь возможность делать это многократно, потому что при работе с большой фермой серверов вы не хотите тратить время на вычисление какие из них немного отклонились из-за некоторого обслуживания или обновления.Вы просто хотите иметь возможность сказать всем серверам сразу :«принять предпочтительную конфигурацию».
Это похоже на то, как если вы пытаетесь управлять комнатой, полной собак, и хотите, чтобы они все сидели, :некоторые из них уже сидят, а другие стоят. Подача команды «сидеть» не повлияет на уже сидящих, но приведет всю комнату в желаемую единую конфигурацию.
Ваша команда:
$(grep -w "xyz" prog.R | wc -l) -ge 3
в контексте команды проверки оболочки:
if [ $(grep -w "xyz" prog.R | wc -l) -ge 3 ]; then
do_something
fi
будет проверять, существует ли xyz
как полное «слово» по крайней мере в 3 строках в prog.R
и устанавливает нулевой статус выхода, если да, а не -ноль в противном случае. См. @Kuslananadas ответ для разбивки этой командной строки.
В качестве альтернативы вы можете просто использовать одну команду awk, например. это в GNU awk:
if awk '/\<wyz\>/ && (++c == 3){ f=1; exit } END{exit !f}' prog.R; then
do_something
fi
или это в любом awk:
if awk '/(^|[^[:alnum:]_])wyz([^[:alnum:]_]|$)/ && (++c == 3){ f=1; exit } END{exit !f}' prog.R; then
do_something
fi
Команда grep
извлекает все строки в файле с именем prog.R
, содержащие слово xyz
. Параметр -w
позволяет сопоставлять только полные слова, поэтому, например, он не будет совпадать. xyzz
или vxyz
.
Команда wc -l
считывает выходные данные из grep
через канал |
и подсчитывает количество строк, созданных командой grep
. Это будет вывод подстановки команды в целом, то есть бит $(...)
.
Если предположить, что подстановка команды($(...)
)находится внутри [... ]
или в качестве аргументов утилиты test
, тогда -ge 3
является проверкой того, является ли количество строк, подсчитанных с помощью wc -l
, больше или равно трем.
test "$(grep -w "xyz" prog.R | wc -l)" -ge 3
или
[ "$(grep -w "xyz" prog.R | wc -l)" -ge 3 ]
Это возвращает статус выхода, который может использоваться оператором if
(как «логическое значение», как вы говорите, например, ), но трудно сказать что-то большее, не видя больше кода..
Без [... ]
или test
команда бессмысленна.
Вы можете проверить руководства по утилитам grep
, wc
и test
и, возможно, прочитать о конвейерах и подстановках команд.
Обратите внимание на то, что я цитировал "$( grep... )"
выше. Без двойных кавычек оболочка разделила бы результат подстановки команд на символы в$IFS
(пробел, табуляция, новая строка, по умолчанию ), а затем применила бы подстановку имени файла к результирующим строкам. Это то, чего мы здесь не очень хотим, тем более, что мы не знаем значение $IFS
(, если оно содержит цифры, по какой-то причине это может повлиять на результат теста ).
См. также:
Тесты grep
и wc
можно сократить до
[ "$(grep -c -w 'xyz' prog.R)" -ge 3 ]
Опция -c
для grep
позволяет сообщать о количестве совпадающих строк, что делает ненужным использование wc -l
.
С GNUgrep
(и некоторыми другими ),весь тест мог бы стать более эффективным (быстрее):
[ "$(grep -c -m 3 -w 'xyz' prog.R)" -eq 3 ]
, где -m 3
останавливает grep
после трех совпадений. С помощью -c
, grep
затем выводит 3
, если хотя бы три строки соответствуют выражению, поэтому мы проверяем с помощью -eq 3
, чтобы увидеть, так ли это.
Опции -m
и -w
для grep
не являются стандартными, но часто(-w
)или иногда(-m
)реализуются.