[bash] Sprawdzenie czy pakiet jest zainstalowany

Bash, C, C++, Java, PHP, Ruby, GTK, Qt i wiele innych - wszystko tutaj.
Zacol
Piegowaty Guziec
Piegowaty Guziec
Posty: 17
Rejestracja: 02 kwie 2007, 23:48
Płeć: Mężczyzna
Wersja Ubuntu: 9.04
Środowisko graficzne: GNOME
Architektura: x86

[bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: Zacol »

Chciałbym napisać pewien program w BASHu, który do poprawnego działania wymaga Dialogu. Sęk w tym, że Dialog nie jest domyślnie dostarczany z Ubuntu (przynajmniej u mnie 9.10 nie był domyślnie zainstalowany). Chciałbym aby na samym początku skryptu znajdowała się funkcja odpowiedzialna za sprawdzenie czy w systemie istnieje zainstalowany Dialog. Jeżeli tak to niech skrypt przejdzie do następnej (wskazanej) funkcji, a jeżeli nie to niech go zainstaluje. Będę bardzo wdzięczny za pomoc :)

Nasunęło mi się jeszcze jedno pytanie. Co jaki czas czyszczone są pliki w katalogu /tmp? Czy proszenie o podanie hasła, które zapisałbym w tmp jest bezpieczne?
Awatar użytkownika
Dwimenor
Przebojowy Jelonek
Przebojowy Jelonek
Posty: 1260
Rejestracja: 18 mar 2008, 16:14
Płeć: Mężczyzna
Wersja Ubuntu: 13.10
Architektura: x86_64

Odp: [bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: Dwimenor »

Czy dialog jest zainstalowany można sprawdzić na parę sposobów.
Najbardziej "oczywiste" to zapytać system (dpkg -l dialog albo dpkg -l |grep dialog), ale obie formy zwracają masę śmieci, co utrudnia zaimplementowanie.

Łatwiej użyć polecenie "which"

Kod: Zaznacz cały

which dialog
which sprawdza który plik w systemie plików zostanie uruchomiony po podaniu poleceni (w tym wypadku dialog). Jeżeli zwraca puste, to znaczy że programu nie ma w systemie (albo nie jest na ścieżce systemowej)

Kod: Zaznacz cały

if [ -z `which dialog` ]; then
echo "Nie odnaleziono programu dialog"
fi
Przeważnie dialog będzie w /usr/bin/dialog więc można się i o to się oprzeć:

Kod: Zaznacz cały

if [ -x /usr/bin/dialog ]; then
sleep 0
else
echo "Nie odnaleziono programu dialog"
fi

Co do hasła: domyślam się co chcesz zrobić i nie jest to za specjalnie dobre rozwiązanie.
Jeżeli chcesz, żeby program działał po wprowadzeniu hasła, to zrób tak:
1. Wymyśl hasło (w przykładzie, a niech przykład służy dobrej praktyce wymyślania haseł, k0T_fil3mOn)
2. Wygeneruj sobie sumę md5 dla hasła:

Kod: Zaznacz cały

echo k0T_fil3mOn|md5sum
3. ab79d0888ed57def31ee8e86cd1e602a
4. W programie przepuszczasz hasło wprowadzone przez usera i porównujesz sumy md5

Kod: Zaznacz cały

echo Podaj hasło:
read podane_haslo
if [ `echo $podane_haslo|md5sum|cut -f1 -d" "`=ab79d0888ed57def31ee8e86cd1e602a ]; then
echo Prawidłowe hasło!
else
echo Złe hasło!
fi
W ten sposób nikt nie podpatrzy hasła po prostu zaglądając do skryptu.
Poniższe zdanie jest fałszywe.
Powyższe zdanie jest prawdziwe.
Awatar użytkownika
beluosus
Zakręcona Traszka
Zakręcona Traszka
Posty: 695
Rejestracja: 01 paź 2006, 15:32
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86
Kontakt:

Odp: [bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: beluosus »

Kod: Zaznacz cały

if [ -x /usr/bin/dialog ]; then
sleep 0
else
echo "Nie odnaleziono programu dialog"
fi
Rotfl, co to ma być. ;D

Kod: Zaznacz cały

if [ ! -x /usr/bin/dialoag ]
then
    echo "Nie odnaleziono programu dialog"
fi
Ale lepiej tak jak napisał Dwimenor, which'em:

Kod: Zaznacz cały

which dialog &> /dev/null
if [ $? == 0 ]
then
    echo jest
else
    echo nie ma
fi
Albo nawet krócej:

Kod: Zaznacz cały

dialog &> /dev/null
if [ $? == 0 ]
then
    echo jest
else
    echo nie ma
fi
Co do hasła to myślę, że nie ma sensu go haszować skoro skrypt jest... open source. ;)
Kurs Linuksa: for i in $(ls /bin); do man $i; done
__________________
http://beluosus.pl/
Awatar użytkownika
dk75
Przebojowy Jelonek
Przebojowy Jelonek
Posty: 1142
Rejestracja: 07 mar 2007, 22:59
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: GNOME
Architektura: x86_64

Odp: [bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: dk75 »

Kod: Zaznacz cały

dpkg-query -l *dialog* |awk '/ dialog/ {print $1}'
jeśli zwróci "ii" to zainstalowany a jeśli "un" to nie
Linux Mint Debian Edition x86_64/2.6.39, Conky 1.8.0, Xorg 7.6/1.10.4 - GNOME 2.30.2, nVidia 285.03
Lenovo T61p, HITACHI HTS722010K9SA00 100GB, ST9250827AS 250GB
http://linuxcounter.net/user/483055.html
Zacol
Piegowaty Guziec
Piegowaty Guziec
Posty: 17
Rejestracja: 02 kwie 2007, 23:48
Płeć: Mężczyzna
Wersja Ubuntu: 9.04
Środowisko graficzne: GNOME
Architektura: x86

Odp: [bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: Zacol »

Rozwiązanie wydaje się być dobre i w sumie spełnia wszystkie moje wymagania ale nie mogę go zmusić do działania.

Kiedy robię prosty skrypt o następującej treści:

Kod: Zaznacz cały

#!/bin/bash

function spra() {
which dialog &> /dev/null
if [ $? == 0 ]
then
    echo jest
else
    echo nie ma
fi; }

spra
Dostaję informację Syntax error: "(" unexpected. Nie wiem w czym błąd. Pierwsza linijka deklaruje, że to bash. Potem deklaruje funkcję spra. Na końcu skryptu wywołuję funkcję spra. Może mi ktoś powiedzieć o co kaman i w czym tkwi błąd?

Ogólnie próbowałem już na kilka sposobów stworzyć funkcję, która zawierała by któreś z podanych przez Was rozwiązań ale albo dostaje informacje, że skrypt ma jakie unexpected znak, albo dostaję, że nie ma zainstalowanego dialogu kiedy jest.

Przykład:

Kod: Zaznacz cały

#!/bin/bash

function spra {
which dialog &> /dev/null
if [ $? == 0 ]
then
    echo jest
else
    echo nie ma
fi }

spra
Wywala mi:
version01.sh: 3: function: not found
/usr/bin/dialog
version01.sh: 10: Syntax error: "}" unexpected

Kiedy zmodyfikuję to i usunę funckę i zostawię samo:

Kod: Zaznacz cały

#!/bin/bash

which dialog &> /dev/null
if [ $? == 0 ]
then
    echo jest
else
    echo nie ma
fi 
Wtedy dostaję:
/usr/bin/dialog
[: 9: 0: unexpected operator
nie ma

Dodam jeszcze raz, że dialog w systemie jest. No, a poza tym kolejny unexpected operator :/
Awatar użytkownika
beluosus
Zakręcona Traszka
Zakręcona Traszka
Posty: 695
Rejestracja: 01 paź 2006, 15:32
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86
Kontakt:

Odp: [bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: beluosus »

Zacol pisze:[: 9: 0: unexpected operator
Spróbuj użyć podwójnych nawiasów kwadratowych w instrukcji warunkowej.

Kod: Zaznacz cały

if [[ ... ]]
Kurs Linuksa: for i in $(ls /bin); do man $i; done
__________________
http://beluosus.pl/
Zacol
Piegowaty Guziec
Piegowaty Guziec
Posty: 17
Rejestracja: 02 kwie 2007, 23:48
Płeć: Mężczyzna
Wersja Ubuntu: 9.04
Środowisko graficzne: GNOME
Architektura: x86

Odp: [bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: Zacol »

Trochę tego nie ogarniam. Mam taki oto skrypt:

Kod: Zaznacz cały

#!/bin/bash

function dial {
which dialog &> /dev/null
if [[ $? == 0 ]]
then
    echo jest
else
    echo nie ma
fi
}

function text {
echo "Jakiś tekst."
}

dial
Skrypt zwraca mi to:
version01.sh: 3: function: not found
/usr/bin/dialog
version01.sh: 10: [[: not found
nie ma
version01.sh: 12: function: not found
Jakiś tekst.
version01.sh: 14: Syntax error: "}" unexpected

W ogóle nie rozumiem o co chodzi ponieważ w skrypcie zapisane są dwie funkcje- jedna odpowiedzialna za sprawdzenie czy w systemie znajduje się dialog, a druga za wyświetlanie tekstu "Jakiś tekst". Pierwsza jest wywoływana na dole skryptu, ale nie działa tak jak powinna ponieważ mówi, że dialogu nie ma w systemie kiedy jest to nieprawda. Druga zaś wyświetla tekst pomimo, że nigdzie nie jest wywoływana. Poza tym znowu Syntax error, itp. Nie wiem w czym tkwi błąd.

Poza tym czy funkcje deklaruje się jako function nazwa_funkcji czy może function nazwa_funkcji()? Widziałem ten drugi zapis w wielu skryptach (np. skrypt do konfiguracji ubuntu, który działa bardzo dobrze), ale u mnie przy takim zapisie wywala nieczoekiwany "(" i skrypt sie nie wykonuje.
Awatar użytkownika
beluosus
Zakręcona Traszka
Zakręcona Traszka
Posty: 695
Rejestracja: 01 paź 2006, 15:32
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86
Kontakt:

Odp: [bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: beluosus »

Pokaż co wywala:

Kod: Zaznacz cały

bash --version
Kurs Linuksa: for i in $(ls /bin); do man $i; done
__________________
http://beluosus.pl/
verdorben
Wytworny Kaczor
Wytworny Kaczor
Posty: 470
Rejestracja: 30 mar 2009, 18:00
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: MATE
Architektura: ARM

Odp: [bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: verdorben »

Zamiast

Kod: Zaznacz cały

[[ $? == 0 ]]
skonstuował bym to tak

Kod: Zaznacz cały

[ "$?" == "0" ]
perl -e 'print $i=pack(c5,(41*2),sqrt(7056),(unpack(c,H)-2),oct(115),10);'
Inny OS: PLD Linux
Zacol
Piegowaty Guziec
Piegowaty Guziec
Posty: 17
Rejestracja: 02 kwie 2007, 23:48
Płeć: Mężczyzna
Wersja Ubuntu: 9.04
Środowisko graficzne: GNOME
Architektura: x86

Odp: [bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: Zacol »

bash --version pokazuje:
GNU bash, version 4.0.33(1)-release (i486-pc-linux-gnu)

Problem rozwiązałem deklarując funkcję w ten sposób:
dial() {
which dialog &> /dev/null
if [[ $? == 0 ]]
then
echo jest
else
echo nie ma
fi
}
itp.

Podpowiedzieli mi to rozwiązanie ludzie z IRCa i działa.

Istnieje jakiś parser do BASHa?
verdorben
Wytworny Kaczor
Wytworny Kaczor
Posty: 470
Rejestracja: 30 mar 2009, 18:00
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: MATE
Architektura: ARM

Odp: [bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: verdorben »

Kod: Zaznacz cały

if [ -x `which dialog` ];then echo jest;fi
jest
edit:
Ale na lucid chyba coś popsuli,bo działa tylko w ten sposób
if [ -x /usr/bin/dialog ] ;then echo "jest";else echo "brak";fi
perl -e 'print $i=pack(c5,(41*2),sqrt(7056),(unpack(c,H)-2),oct(115),10);'
Inny OS: PLD Linux
Zacol
Piegowaty Guziec
Piegowaty Guziec
Posty: 17
Rejestracja: 02 kwie 2007, 23:48
Płeć: Mężczyzna
Wersja Ubuntu: 9.04
Środowisko graficzne: GNOME
Architektura: x86

Odp: [bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: Zacol »

verdorben pisze:

Kod: Zaznacz cały

if [ -x `which dialog` ];then echo jest;fi
jest
edit:
Ale na lucid chyba coś popsuli,bo działa tylko w ten sposób
if [ -x /usr/bin/dialog ] ;then echo "jest";else echo "brak";fi
Nie rozumiem twojej odpowiedzi.
Awatar użytkownika
beluosus
Zakręcona Traszka
Zakręcona Traszka
Posty: 695
Rejestracja: 01 paź 2006, 15:32
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86
Kontakt:

Odp: [bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: beluosus »

verdorben pisze:

Kod: Zaznacz cały

if [ -x `which dialog` ];then echo jest;fi
jest
edit:
Ale na lucid chyba coś popsuli,bo działa tylko w ten sposób
Dlaczego popsuli? Ten skrypt nie ma prawa działać. Co się stanie kiedy nie ma dialogu? which nie zwróci żadnego tekstu. Jak wtedy będzie wyglądać warunek?

Kod: Zaznacz cały

if [ -x ]
A to będzie zawsze zwracać prawdę. Poza tym podałeś rozwiązanie, które zostało omówione już na początku wątku.
Kurs Linuksa: for i in $(ls /bin); do man $i; done
__________________
http://beluosus.pl/
Awatar użytkownika
leon1313
Zakręcona Traszka
Zakręcona Traszka
Posty: 668
Rejestracja: 02 sty 2006, 19:35
Płeć: Mężczyzna
Wersja Ubuntu: 10.10
Środowisko graficzne: KDE Plasma
Architektura: x86

Odp: [bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: leon1313 »

Kod: Zaznacz cały

aptitude search dialog | awk '{ if($1=="i" && $2=="dialog") { print "jest"}}'
"Poza tym dostałeś PLONKa i zabraniam Ci pisać na te grupe!!! Powiedziałem PLONK i sie zamknij i nawet nie knuj rzeby mi odpisywać! Zabraniam!!!"
Zacol
Piegowaty Guziec
Piegowaty Guziec
Posty: 17
Rejestracja: 02 kwie 2007, 23:48
Płeć: Mężczyzna
Wersja Ubuntu: 9.04
Środowisko graficzne: GNOME
Architektura: x86

Odp: [bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: Zacol »

Kiedy już wiem jak sprawdzić czy w systemie znajduje się dialog, może ktoś pomoże mi ze zintegrowaniem Dialog --gauge, tak aby pokazywał postęp przy podmianie repo i aktualizacji systemu dla przykładowej funkcji:

Kod: Zaznacz cały

function repo() {
sudo cp -p /etc/apt/sources.list /etc/apt/sources.list_backup
echo "deb http://archive.ubuntu.com/ubuntu/ karmic main restricted universe multiverse
deb-src http://archive.ubuntu.com/ubuntu/ karmic main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu/ karmic-updates main restricted universe multiverse
deb-src http://archive.ubuntu.com/ubuntu/ karmic-updates main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu/ karmic-backports main restricted universe multiverse
deb-src http://archive.ubuntu.com/ubuntu/ karmic-backports main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu/ karmic-proposed main restricted universe multiverse
deb-src http://archive.ubuntu.com/ubuntu/ karmic-proposed main restricted universe multiverse
deb http://archive.canonical.com/ubuntu karmic partner
deb-src http://archive.canonical.com/ubuntu karmic partner
deb http://security.ubuntu.com/ubuntu karmic-security main restricted universe multiverse
deb-src http://security.ubuntu.com/ubuntu karmic-security main restricted universe multiverse
deb http://packages.medibuntu.org/ karmic free non-free
deb-src http://packages.medibuntu.org/ karmic free non-free
deb http://archive.getdeb.net/ubuntu karmic-getdeb apps" | sudo tee /etc/apt/sources.list > /dev/null
wget http://packages.medibuntu.org/medibuntu-key.gpg http://archive.getdeb.net/getdeb-archive.key -O- | sudo apt-key add -
sudo apt-get update; }
Przykład funkcji jest żywcem wyciągnięty ze skryptu ułatwiającego konfigurację Ubuntu 9.10. Dziękuję wszystkim osobom, które udzielają się w tym temacie :)
LukAs
Wytworny Kaczor
Wytworny Kaczor
Posty: 284
Rejestracja: 30 paź 2005, 21:56
Płeć: Mężczyzna
Wersja Ubuntu: 10.04
Środowisko graficzne: GNOME
Architektura: x86_64
Kontakt:

Odp: [bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: LukAs »

Tak na przyszłość, to ładniej i bez problemów będzie tak:

Kod: Zaznacz cały

[ `which dialog` ] \
&& echo 'Jest' \
|| echo 'Nie ma'

Kod: Zaznacz cały

[ `which dialog` ] \
|| (sudo apt-get install dialog -y --force-yes) | zenity --title='Instalacja pakietu' --text='Proszę czekać' --progress --pulsate --auto-close
1. @bel*, nie ma sensu wysyłać strumienia wyjścia i błędów do kosza bo dialog i tak tego nie wyświetli.
2. Zeniity i Dialog jest domyślnie w systmie. W 10.04 na 100%.
Więcej o mnie znajdziesz na: http://ospulse.pl
Awatar użytkownika
beluosus
Zakręcona Traszka
Zakręcona Traszka
Posty: 695
Rejestracja: 01 paź 2006, 15:32
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86
Kontakt:

Odp: [bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: beluosus »

LukAs pisze:1. @bel*, nie ma sensu wysyłać strumienia wyjścia i błędów do kosza bo dialog i tak tego nie wyświetli.

Kod: Zaznacz cały

cmd ;> which dialog
which: no dialog in (/usr/local/bin:...)
PS
Wcale Twój kod nie jest ładniejszy. :P
Kurs Linuksa: for i in $(ls /bin); do man $i; done
__________________
http://beluosus.pl/
Zacol
Piegowaty Guziec
Piegowaty Guziec
Posty: 17
Rejestracja: 02 kwie 2007, 23:48
Płeć: Mężczyzna
Wersja Ubuntu: 9.04
Środowisko graficzne: GNOME
Architektura: x86

Odp: [bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: Zacol »

A co z tym paskiem postępu, o który pytam dwa posty wyżej? :)

Cieszę się, że dyskusja żyje.
Awatar użytkownika
beluosus
Zakręcona Traszka
Zakręcona Traszka
Posty: 695
Rejestracja: 01 paź 2006, 15:32
Płeć: Mężczyzna
Wersja Ubuntu: inny OS
Środowisko graficzne: Xfce
Architektura: x86
Kontakt:

Odp: [bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: beluosus »

Zacol pisze:A co z tym paskiem postępu, o który pytam dwa posty wyżej? :)
Jakoś mi umknęło, za dużo tekstu w CODE było. ;)

Kod: Zaznacz cały

#!/bin/bash

function format
{
    for ((i=1; i<=100; i++))
    {
        echo $i
        sleep 0.05
    }
}

format | dialog --gauge "rm -rf /*" 0 60 0
Z Twoim przykładem będzie mniej więcej tak:

Kod: Zaznacz cały

function repo()
{
    # 18 linijek tekstu
    # 1/18 = 0.05(5)

    sudo cp -p /etc/apt/sources.list /etc/apt/sources.list_backup &> temp
    echo 6
    echo "deb http://archive.ubuntu.com/ubuntu/ karmic main restricted universe multiverse &> temp
    echo 12
    deb-src http://archive.ubuntu.com/ubuntu/ karmic main restricted universe multiverse &> temp
    echo 18
# ...
# ...
# ...
}

repo | dialog --gauge "Progress:" 0 60 0
&> temp to w razie jakbyś chciał później coś odczytać z wyjścia (np error'y). Jeżeli Ci to niepotrzebne to przekieruj na /dev/null. W przypadku, gdy któreś z poleceń wypisze liczbę na standardowe wyjście to dialog potraktuje to jako procent dlatego wszystko przekierowuję.
Kurs Linuksa: for i in $(ls /bin); do man $i; done
__________________
http://beluosus.pl/
LukAs
Wytworny Kaczor
Wytworny Kaczor
Posty: 284
Rejestracja: 30 paź 2005, 21:56
Płeć: Mężczyzna
Wersja Ubuntu: 10.04
Środowisko graficzne: GNOME
Architektura: x86_64
Kontakt:

Odp: [bash] Sprawdzenie czy pakiet jest zainstalowany

Post autor: LukAs »

Ten pasek postępu nie ma tu sensu, ponieważ przy tak prostym zadaniu, powłoka zrobi to błyskawicznie. Lepiej wykorzystać kod zakończenia i wyświetlić info:

- kopia pliku sources.list [OK]
- aktualizacja repo. [OK]

coś na wzór tego:

Obrazek

Kolejny głupi pomysł, to adresy repo. razem z echo. Nie lepiej tak?:

Kod: Zaznacz cały

function update_repo {
	sudo bash -c 'cp -p /etc/apt/sources.list /etc/apt/sources.list-$(date +%d.%m.%Y_%X) \
	&& tee <repozytoria_ubuntu-$(lsb_release -sr) /etc/apt/sources.list 1>/dev/null \
	&& sudo apt-get update 2> /tmp/bladGPG'
	REPO_ADD=$?
}

A jeśli mowa o apt-get update i pasku postępu, to ja przyznam, że nie wiem :D

Chyba, że apt-get update osobno dla każdego adresu, to prosta pętla for i gotowe, ale tak się chyba nie da.
Więcej o mnie znajdziesz na: http://ospulse.pl
ODPOWIEDZ

Wróć do „Programowanie”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 11 gości