2

У меня есть скрипт 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 ответа2

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

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

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

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

Но...

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

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .