Как я могу идемпотентно pecl установить модуль дважды?

492
spraff

У меня есть скрипт bash, который должен быть повторно запущен. Это включает

pecl install foo || { echo "Could not install foo!"; exit 1; } 

Если это выполняется дважды, это ошибки

pecl/foo is already installed and is the same as the released version 1.2.3 install failed Could not install foo! 

В отличие от таких инструментов, как apt-get или yum, pecl возвращает код ошибки, если модуль уже установлен, тогда как я хочу, чтобы он сообщал об успехе.

Я мог бы захватить и grep stdout / stderr, но есть ли менее хакерский способ добиться того же?

2
Превосходное использование слова «идемпотентно» - пришлось его искать, но оно прекрасно описывает ситуацию. Argonauts 7 лет назад 0

2 ответа на вопрос

1
spraff
if ! pecl list | grep foo >/dev/null 2>&1; then pecl install foo || { echo_err "Could not pecl install foo"; exit 1; } fi 
1
Argonauts

Вы можете различать и маскировать

возвращаемое значение из pecl install fooкоманды с методикой ниже. Он сохраняет возвращаемое значение из вызова, но команда 'true' эффективно маскирует его, поэтому оператор возвращает 0 независимо от значения retVal.

pecl install foo >/dev/null 2>&1 || { retVal=$?; true; } 

Но...

это не очень поможет, поскольку, по- pecl installвидимому, возвращает значение 1 независимо от характера ошибки - быстрый тест показал, что уже установленный пакет или ошибка не найденного пакета вернут 1.

Поэтому вместо этого я бы просто проверил, установлен ли пакет перед вызовом pecl install.

Чтобы проверить, установлен ли пакет, я предполагаю, что имя не включает префикс pecl, например, jsonc, а не pecl / jsonc; и что вывод из pecl list-all всегда будет начинаться с pecl. Для пояснения, скажем, мы работаем с пакетом jsonc:

 pkg="jsonc" pecl list-all | grep "$pkg" 

Результатом будет такой вывод (при условии, что он установлен):

pecl/jsonc 1.3.10 JavaScript Object Notation 

Чтобы избежать ложного объявления установленного пакета, регулярное выражение, используемое с grep, использует этот формат вывода - если мы просто сопоставим имя пакета, совпадение с jsonc также будет совпадением с jsoncde (а не с реальным пакетом). Таким образом, регулярное выражение ищет начало строки, за которой pecl/следует имя пакета, с пробелом после имени пакета:"^pecl/$pkg "

Вам может потребоваться изменить это регулярное выражение на основе возможных имен используемых пакетов.

#!/bin/bash  if [ $# -lt 1 ]; then echo "Package name must be passed as sole argument" exit 2 else pkg="$1" fi  if pecl list-all | grep -Eq "^pecl/$pkg " ; then echo "package $pkg is already installed" exit 0 else # not installed if pecl -q install "$pkg" >/dev/null ; then echo "Package $pkg installed successfully" exit 0 else echo "Error occurred during installation of $pkg" exit 1 fi fi 

Если pecl list-all | grep ...команда ведет себя неправильно при проверке установленных пакетов, вы также можете использовать эту команду pecl info $pkg. Я не особо разбирался в этом, но, похоже, он возвращает 0 (и кучу информации в stdout), когда запрашиваемый пакет установлен, и возвращает 1, когда пакет не установлен (и ошибку в stderr ).

Похожие вопросы