Проверьте, установлен ли пакет в APT

10

Я хочу, чтобы метод сценария оболочки тестировал / сообщал, если установлен пакет. Мне не нужны детали, только логическое возвращение для установки логического потока. Я посмотрел на Find, если пакет установлен , но dpkgвозвращает сложный вывод и его формат меняется в зависимости от того, находится ли пакет в репозитории Debian или в Ubuntu PPA.

Я обнаружил, что это apt-cacheделает довольно хорошую работу, и я придумал этот метод:

is_installed=0
test_installed=( `apt-cache policy package-name | grep "Installed:" ` )
[ ! "${test_installed[1]}" == "(none)" ] && is_installed=1

Кто-нибудь знает более простой или более прямой путь?

tahoar
источник

Ответы:

12

dpkg-query так как в вашей связанной публикации, кажется, самый правильный инструмент для работы, за исключением использования, например, доступных библиотек Python для непосредственного связывания с системой APT в таком контексте сценариев.

С dpkg-query:

dpkg-query -Wf'${db:Status-abbrev}' package-name 2>/dev/null | grep -q '^i'

Возвращает значение true (состояние выхода 0в сценарии оболочки), если пакет установлен, в 1противном случае - значение false (состояние выхода ).

  • -Wозначает «Показать» ( dpkg-queryдолжно иметь запрошенное действие).
  • -f меняет формат вывода.
  • db:Status-abbrev это краткая форма статуса пакета.
  • 2>/dev/nullзаставляет замолчать, dpkg-queryесли задано неверное имя пакета. Как это следует делать, может быть вопросом от случая к случаю.
  • grep -q возвращает true, если есть совпадение, иначе false.

Если это используется часто, это может быть сделано простой функцией:

#!/bin/sh
debInst() {
    dpkg-query -Wf'${db:Status-abbrev}' "$1" 2>/dev/null | grep -q '^i'
}

if debInst "$1"; then
    printf 'Why yes, the package %s _is_ installed!\n' "$1"
else
    printf 'I regret to inform you that the package %s is not currently installed.\n' "$1"
fi

или просто

#!/bin/sh
if dpkg-query -Wf'${db:Status-abbrev}' "$1" 2>/dev/null | grep -q '^i'; then
    printf 'Why yes, the package "%s" _is_ installed!\n' "$1"
else
    printf 'I regret to inform you that the package "%s" is not currently installed.\n' "$1"
fi
Даниэль Андерссон
источник
Хотя это, несомненно, правильно, я считаю, что этого dpkg-query -l "$package" | grep -q ^.iобычно достаточно (и легче запомнить).
Фогг
1
@phogg: Да, зависит от того, должен ли он жить в сценарии или нет. Кроме того, dpkg-query -lвывод не установлен в камне, так как это просто режим пользовательской презентации, поэтому, если презентация изменится, возможно, такой скрипт сломается.
Даниэль Андерссон
@Daniel. Мне нравится подход кода возврата. Пожалуйста, смотрите мой ответ с подробностями в коде.
Тахоар
10.04 вариант формата db: Status-abbrev, кажется, не существует - я использовал: dpkg-query -Wf'${Version}' ${pkg} 2>/dev/null | grep -q '^\d*'с тем же эффектом.
Скоттиномад
1

Я проверил предложения Дэниела на трех пакетах с этими результатами:

  1. Собственный пакет репозитория Debian не установлен:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' apache-perl
    ~$ echo $?
    1
    
  2. Пакет PPA зарегистрирован на хосте и установлен:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' libreoffice
    ~$ echo $?
    0
    
  3. Пакет PPA зарегистрирован на хосте, но не установлен:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' domy-ce
    ~$ echo $?
    0
    ~$ sudo apt-get remove domy-ce
    [sudo] password for user: 
    Reading package lists... Done
    Building dependency tree       
    Reading state information... Done
    Package domy-ce is not installed, so not removed
    0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
    

Хотя мне нравится подход, кажется, я не могу доверять коду возврата пакетов PPA. Если не считать этого, я думаю, что я буду придерживаться синтаксического анализа возврата apt-cache policyкоманды.

tahoar
источник
Ну, ваши примеры кода - это не то, что я сказал, что вы должны делать, но я думаю, вы только что пропустили grepроль в своем вставке. Я не могу воспроизвести вашу проблему, но это может быть из-за того, что примеры кода в настоящее время неполные, поэтому, пожалуйста, исправьте это. Вы запускаете Debian или Ubuntu?
Даниэль Андерссон
Я использую Ubuntu 10.04 (PPA не поддерживается прямым Debian?). Мой код отбросил ваш grep, потому что 1) команда dkpg-query ничего не записывает в stdout, а grep всегда выдает код возврата. Код возврата dpkg-запроса равен 0, если установлен.
Тахоар
2
1. Не помечайте свой пост "Debian" тогда. 2. Я не думаю, что вы поняли роль, grepсыгранную в команде, поэтому вы сняли ее, и теперь вы говорите, что она не работает? grep -qдает код возврата, 1если он не совпадает, то есть программа не установлена ​​или недоступна, или 0если программа установлена. Я объяснил это в моем посте.
Даниэль Андерссон
1
#!/bin/bash

# Check for dependencies 
check_deps () {
DEPS=$(echo {dialog,sqlite3,openssh-client})
for i in $DEPS ; do
    dpkg-query -W -f='${Package}\n' | grep ^$i$ > /dev/null
    if [ $? != 0 ] ; then
        echo "Installing deps ..."
        aptitude install $i -y > /dev/null
    fi
done  
}

# execute the check_deps function
check_deps
Диего Роберто Дос Сантос
источник
-1, вопрос не в проверке зависимостей. Также объясните, что делают части команды: в противном случае другие люди не могут видеть, что происходит.
Даниэль Андерссон
DEPS=$(echo {dialog,sqlite3,openssh-client})может быть эквивалентно написано как просто DEPS="dialog sqlite3 openssh-client".
Даниэль Андерссон
1

Мне нравится ответ Даниэля Андерссона, но он не сработал для меня. Я на Ubuntu 12.04.

Со страницы руководства dpkg , db:Status-abbrevработает только в dpkg 1.16.2+:

          db:Status-Abbrev
                 It  contains the abbreviated package status, such as “ii”
                 (since dpkg 1.16.2).

Мое решение состояло в том, чтобы использовать устаревшее поведение, только Statusформатер:

dpkg-query -Wf'${Status}' {my_pkg_name}

выходы

install ok installed 

Я предполагаю, что это было вдохновением для «ii» в других представлениях.

Итак, чтобы полностью адаптировать ответ Дэниела Андерссона для работы с более старой версией dpkg и, следовательно, со старыми дистрибутивами Ubuntu:

dpkg-query -Wf'${Status}' {your_pkg_name} 2>/dev/null | grep -q "install ok installed"

Возвращает:

  • 0 - пакет установлен, или
  • 1 - пакет НЕ установлен.
Уилбур Уэйтли
источник