Bir paketin kurulu olup olmadığını güvenilir bir şekilde kontrol edin


20

Basit bir gereksinim var. Bir kabuk betiği aracılığıyla kurmak istediğim belirli sayıda pakete karşılık gelecek birkaç değişken tanımlamak istiyorum.

Aşağıdaki örnek kod:

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

Her şey çalışıyor, ama mantık hatalı görünüyor çünkü istediğim paketleri güvenilir bir şekilde kurmuyor. Ya zaten kurulmuş olduklarını ya da daha önce kurulmuş paketleri kurmaya çalıştığını söylüyor.

Ayrıca şunu da deniyorum command -v:

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

Ve döndürülen dizenin boş olup olmadığını kontrol etmek için -nve -zbayraklarıyla bile . Eminim burada bazı iyi duygular özlüyorum.

Bir paketin gerçekten kurulu olup olmadığından emin olmak için ne yapabileceğim hakkında bir fikrin var mı?

Teşekkürler!


Eğer apt-get installkurulu paketleri de ararsanız, bunun zararı var mı? Sadece arayabilirsin apt-get install $MISC $WEB.
jarno

Yanıtlar:


15

Temel olarak, ifdurumu yalnızca

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

Kullanılması mümkün değildir dpkg-query, çünkü kaldırılmış ancak temizlenmemiş paketler için de doğru olur.

Ayrıca apt-getbaşarılı mesajı vermeden önce çıkış kodunu kontrol etmenizi öneririz :

if apt-get -qq install $pkg; then
    echo "Successfully installed $pkg"
else
    echo "Error installing $pkg"
fi

Ne yapar &>?
Taymon,

@Taymon: stdin ve stderr komutunu verilen dosyaya yönlendirir ( /dev/nullbu durumda), çünkü çıktıya ihtiyacımız yoktur, sadece çıkış kodunu kullanırız. Sadece çalışır bash(betiğin ilk satırı olmalıdır #!/bin/bash) aksi takdirde kullanılır >/dev/null 2>&1.
enzotib

@Taymon: Mantığı değiştirdim, çünkü önceki çözümde bir kusur buldum.
enzotib

Dikkat: bash kullanıyorsanız ve pipefail seçeneği ayarlanmışsa, grep -q Heisenbugs oluşturabilir. Temel olarak, grp dpkg yazmayı bitirmeden önce çıkar (bu durumda 0 çıkış durumu istiyorsanız), bu nedenle dpkg boruya yazı yazamaz (bunun yerine 0 olmayan bir çıkış durumu oluşturur). Ya boru arızasının ayarlanmadığından emin olun ya da "-q" seçeneğinin (muhtemelen küçük) verimlilik kazancını bırakın.
Ron Burk,

2

Dpkg-query ile test edebilirsiniz:

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

* Ve? joker karakterler, eğer $ pkg. Sanırım dpkg-query, eğer paket kırılmış ve apt-get install --reinstallyeni paketleri yüklemek için kullanılabilecek bir komutla yeniden kurulmaları gerekiyorsa, "tamam yüklendi" yerine "yeniden başlatılması gerekiyor" yazdırabilir .


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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.