Periksa apakah paket diinstal atau tidak

20

Saya punya persyaratan sederhana. Saya ingin mendefinisikan beberapa variabel yang akan sesuai dengan sejumlah paket yang diberikan yang ingin saya instal melalui skrip shell.

Contoh kode di bawah ini:

MISC="shutter pidgin"
WEB="apache2 mongodb"

for pkg in $MISC $WEB; do
    if [ "dpkg-query -W $pkg | awk {'print $1'} = """ ]; then
        echo -e "$pkg is already installed"
    else
        apt-get -qq install $pkg
        echo "Successfully installed $pkg"
    fi
done

Semuanya agak berfungsi, tetapi logika tampaknya cacat karena itu tidak dapat dipercaya menginstal paket yang saya inginkan. Entah itu mengatakan mereka sudah diinstal atau sedang mencoba untuk menginstal paket yang sudah diinstal sebelumnya.

Saya juga sudah mencoba dengan command -vatau yang berikut:

if [ "dpkg -l | awk {'print $2'} | grep --regexp=^$pkg$ != """ ]; then

Dan bahkan dengan -ndan-z bendera untuk memeriksa apakah string yang dikembalikan kosong. Cukup yakin saya kehilangan akal sehat di sini.

Apakah Anda tahu apa yang bisa saya lakukan untuk memastikan paket benar-benar diinstal atau tidak?

Terima kasih!

vanz
sumber
Apa salahnya, jika Anda memanggil apt-get installpaket yang diinstal juga? Anda bisa menelepon apt-get install $MISC $WEB.
jarno

Jawaban:

15

Pada dasarnya Anda hanya perlu mengganti ifkondisinya

if dpkg --get-selections | grep -q "^$pkg[[:space:]]*install$" >/dev/null; then

Itu tidak mungkin untuk digunakan dpkg-query , karena ia mengembalikan true juga untuk paket yang dihapus tetapi tidak dibersihkan.

Saya juga menyarankan untuk memeriksa kode keluar apt-getsebelum memberikan pesan yang berhasil:

if apt-get -qq install $pkg; then
    echo "Successfully installed $pkg"
else
    echo "Error installing $pkg"
fi
enzotib
sumber
Apa yang &>harus dilakukan
Taymon
@ Tommon: mengarahkan ulang stdin dan stderr ke file yang diberikan ( /dev/nulldalam hal ini), karena kita tidak memerlukan output, hanya kode keluar. Ini hanya berfungsi di bash(baris pertama skrip harus #!/bin/bash) jika tidak digunakan >/dev/null 2>&1.
enzotib
@ Tommon: Saya mengubah logika, karena saya menemukan kesalahan dalam solusi sebelumnya.
enzotib
Hati-hati: jika menggunakan bash dan opsi pipefail diatur, maka grep -q dapat menghasilkan Heisenbugs. Pada dasarnya, grep keluar sebelum dpkg selesai menulis (Anda ingin 0 status keluar dalam kasus itu) sehingga dpkg gagal menulis ke pipa (yang malah menghasilkan status keluar non-0). Pastikan pipefail tidak disetel, atau abaikan keuntungan efisiensi (mungkin kecil) dari opsi "-q".
Ron Burk
2

Anda dapat mengujinya dengan dpkg-query:

if dpkg-query -W -f'${Status}' "$pkg" 2>/dev/null | grep -q "ok installed"; then

Perhatikan bahwa * dan? adalah wildcard, jika muncul dalam $ pkg. Saya kira dpkg-query dapat mencetak "instal-diperlukan diinstal" bukan "ok diinstal", jika paket rusak dan perlu diinstal ulang dengan perintah apt-get install --reinstallyang dapat digunakan untuk menginstal paket baru juga.

jarno
sumber
0
#to check package is installed or not without distribution dependency
#!/bin/bash
read -p "Package Name: " pkg
which $pkg > /dev/null 2>&1
if [ $? == 0 ]
then
echo "$pkg is already installed. "
else
read -p "$pkg is not installed. Answer yes/no if want installation_ " request
if  [ $request == "yes" ]
then
yum install $pkg
fi
fi
Pak Linux
sumber