Как я могу идемпотентно pecl установить модуль дважды?
У меня есть скрипт 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, но есть ли менее хакерский способ добиться того же?
4 ответа
if ! pecl list | grep foo >/dev/null 2>&1;
then
pecl install foo ||
{
echo_err "Could not pecl install foo";
exit 1;
}
fi
Вы можете различать и маскировать
возвращаемое значение из 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 ).
Я обошел это, просто удалив модуль, так как если модуль не существует и вы делаете деинсталляцию, он возвращает 0, а поскольку в моем случае это редкая работа, дополнительная переустановка не имеет значения.
Почему бы просто не сделать вид, что установил(-p
вариант), а затем установить, если все в порядке?
set -e
if pecl install -p -- "$PACKAGE"; then
pecl install -- "$PACKAGE"
fi