Uji apakah paket diinstal di APT

10

Saya ingin metode skrip shell untuk menguji / melaporkan jika suatu paket diinstal. Saya tidak perlu detail, hanya kembali boolean untuk mengatur aliran logika. Saya melihat Find jika suatu paket diinstal , tetapi dpkgmengembalikan output yang kompleks dan perubahan formatnya tergantung pada apakah paket tersebut ada di repositori Debian atau dalam PPA Ubuntu.

Saya menemukan bahwa apt-cachemelakukan pekerjaan yang cukup bagus dan saya datang dengan metode ini:

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

Adakah yang tahu cara yang lebih sederhana atau lebih langsung?

tahoar
sumber

Jawaban:

12

dpkg-query seperti pada posting Anda yang terhubung tampaknya menjadi alat yang paling tepat untuk pekerjaan itu, kecuali menggunakan misalnya pustaka Python yang tersedia untuk mengikat langsung ke sistem APT dalam konteks scripting seperti itu.

Dengan dpkg-query:

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

Akan mengembalikan true (status keluar 0dalam skrip shell) jika paket diinstal, false (status keluar 1) sebaliknya.

  • -Wberarti "Tunjukkan" ( dpkg-queryharus memiliki tindakan yang diminta).
  • -f mengubah format output.
  • db:Status-abbrev adalah bentuk singkat dari status paket.
  • 2>/dev/nullhening dpkg-queryjika nama paket tidak valid diberikan. Bagaimana ini harus ditangani bisa menjadi masalah kasus per kasus.
  • grep -q mengembalikan true jika ada kecocokan, false sebaliknya.

Jika sering digunakan, itu bisa dibuat fungsi sederhana:

#!/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

atau hanya sederhana

#!/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
Daniel Andersson
sumber
Meskipun ini pasti benar, saya menemukan bahwa dpkg-query -l "$package" | grep -q ^.ibiasanya cukup (dan lebih mudah diingat).
phogg
1
@phogg: Ya, tergantung pada apakah itu seharusnya hidup dalam skrip atau tidak. Juga, dpkg-query -loutput tidak disetel karena ini hanya mode presentasi pengguna, jadi jika presentasi berubah mungkin skrip seperti itu akan rusak.
Daniel Andersson
@Aniel. Saya suka pendekatan kode kembali. Silakan lihat jawaban saya dengan detail dalam kode.
tahoar
Pada 10,04 opsi format db: Status-singkatan tampaknya tidak ada - Saya menggunakan: dpkg-query -Wf'${Version}' ${pkg} 2>/dev/null | grep -q '^\d*'dengan efek yang sama.
scottynomad
1

Saya menguji saran Daniel pada tiga paket dengan hasil ini:

  1. Paket repositori Native Debian tidak diinstal:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' apache-perl
    ~$ echo $?
    1
    
  2. Paket PPA terdaftar di host dan diinstal:

    ~$ dpkg-query -Wf'${db:Status-abbrev}' libreoffice
    ~$ echo $?
    0
    
  3. Paket PPA terdaftar di host tetapi tidak diinstal:

    ~$ 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.
    

Meskipun saya suka pendekatannya, sepertinya saya tidak bisa mempercayai kode kembali dengan paket PPA. Singkatnya, saya pikir saya akan tetap dengan parsing kembalinya apt-cache policyperintah.

tahoar
sumber
Nah, contoh kode Anda bukan yang saya katakan harus Anda lakukan, tapi saya kira Anda baru saja melewatkan grepbagian dalam menempelkan Anda. Saya tidak dapat mereproduksi masalah Anda, tapi itu mungkin karena contoh kode saat ini tidak lengkap, jadi tolong perbaiki itu. Apakah Anda menjalankan Debian atau Ubuntu?
Daniel Andersson
Saya menjalankan Ubuntu 10,04 (apakah PPA didukung tanpa Debian langsung?). Kode saya menjatuhkan grep Anda karena 1) perintah dkpg-query tidak menulis apa pun untuk stdout dan grep selalu melempar returncode. Returncode dpkg-query adalah 0 jika diinstal.
tahoar
2
1. Jangan beri tag pada posting Anda "Debian". 2. Saya tidak berpikir Anda mengerti bagian yang grepdimainkan dalam perintah, jadi Anda melepaskannya, dan sekarang Anda mengatakan itu tidak berhasil? grep -qmemberikan kode pengembalian 1jika tidak cocok, yaitu program tidak diinstal atau tidak tersedia, atau 0jika program diinstal. Saya menjelaskan hal itu di posting saya.
Daniel Andersson
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
Diego Roberto Dos Santos
sumber
-1, pertanyaannya bukan tentang pemeriksaan ketergantungan. Juga, jelaskan apa yang dilakukan bagian-bagian perintah: jika tidak, orang lain tidak dapat melihat apa yang terjadi
Daniel Andersson
DEPS=$(echo {dialog,sqlite3,openssh-client})dapat ditulis secara setara sebagai adil DEPS="dialog sqlite3 openssh-client".
Daniel Andersson
1

Saya suka jawaban Daniel Andersson, tetapi itu tidak berhasil untuk saya. Saya di Ubuntu 12,04.

Dari halaman manual dpkg , db:Status-abbrevhanya berfungsi di dpkg 1.16.2+:

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

Solusi saya adalah menggunakan perilaku lawas, hanya Statusformatter:

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

output

install ok installed 

Saya menduga ini adalah inspirasi untuk "ii" di representasi lain.

Jadi, untuk sepenuhnya mengadaptasi jawaban Daniel Andersson untuk bekerja pada versi dpkg yang lebih lama, dan dengan demikian distro Ubuntu yang lebih tua:

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

Pengembalian:

  • 0 - paket diinstal, atau
  • 1 - paket TIDAK diinstal.
Wilbur Whateley
sumber