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


10

Я хочу, щоб метод сценарію оболонки перевіряв / повідомляв, чи встановлено пакет. Мені не потрібні деталі, тільки булеве повернення, щоб встановити логічний потік. Я подивився на пошук встановленого пакета , але 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

Хтось знає простіший або прямий спосіб?

Відповіді:


12

dpkg-query як у вашому зв’язаному дописі, здається, є найбільш правильним інструментом для роботи, за винятком використання, наприклад, наявних бібліотек Python для прив’язки безпосередньо до системи APT у такому сценарії сценаріїв.

З dpkg-query:

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

Повернеться true (статус виходу 0у скрипті оболонки), якщо пакет встановлений, false (статус виходу 1) в іншому випадку.

  • -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: Статус-абревіатура, здається, не існує - я використовував: dpkg-query -Wf'${Version}' ${pkg} 2>/dev/null | grep -q '^\d*'з тим же ефектом.
scottynomad

1

Я перевірив пропозиції Даніеля щодо трьох пакетів з такими результатами:

  1. Пакет сховища Native 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команди.


Ну, ваші приклади коду - це не те, що я сказав, що ви повинні робити, але, мабуть, ви просто пропустили grepчастину свого вставлення. Я не можу відтворити вашу проблему, але це може бути тому, що приклади коду наразі неповні, тому, будь ласка, виправте це. Ви запускаєте Debian або Ubuntu?
Даніель Андерссон

Я запускаю Ubuntu 10.04 (чи підтримується PPA немає прямого Debian?) Мій код скинув ваш греп, тому що 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 - пакет НЕ встановлений.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.