Przy okazji tego wątku na Forum, postanowiłem odświeżyć sobie działanie tablic w Bashu.
Poprosiłem użytkownika, żeby sprawdził, jakie pakiety ma zainstaloane, a jakich nie ma w ten sposób:
Code:
#!/bin/bash
RPMS=( TESTOWY_NIE_MA_TAKIEGO_PAKIETU nie_ma cheese-lang gdm-lang gnome-contacts-lang
gnome-control-center-color
gnome-control-center-goa gnome-control-center-lang gnome-session-lang gnome-session-wayland
gnome-shell-calendar gnome-shell-classic gnome-shell-extension-gpaste gnome-shell-lang
gnome-shell-search-provider-bijiben gnome-shell-search-provider-contacts
gnome-shell-search-provider-documents gnome-shell-search-provider-nautilus gnome-tweaks-lang
gstreamer-plugins-bad-lang libpurple-lang libpurple-tcl pidgin pulseaudio-gdm-hooks cheese
gnome-shell-extension-desktop-icons gnome-contacts gnome-tweaks libpurple patterns-gnome-gnome
patterns-gnome-gnome_imaging patterns-gnome-gnome_office patterns-gnome-gnome_utilities
libpurple-branding-openSUSE patterns-gnome-gnome_x11 gstreamer-plugins-farstream
patterns-gnome-gnome_basic libfarstream-0_2-5 patterns-gnome-gnome_basis gdm-branding-openSUSE
gdm gnome-shell gnome-session-default-session gnome-session gnome-control-center libcheese-gtk25
libcheese8 gstreamer-plugins-bad
)
for i in ${RPMS[@]}; do
rpm -q --queryformat "%{NAME}\n" $i
done
Działa, ale wynik nie jest posortowany. Dodajmy więc dwie puste tablice:
Code:
INSRPMS=()
MISRPMS=()
i poprośmy Basha, by uzupełniał je w zależności od exit code'u: jak jest 0, to paczka jest zainstalowana, a jak nie zero, to paczki nie ma:
Code:
for i in ${RPMS[@]}; do
rpm -q --queryformat "%{NAME}\n" $i &> /dev/null
if [ $? -eq 0 ]; then
INSRPMS=(${INSRPMS[@]} "$i")
else
MISRPMS=(${MISRPMS[@]} "$i")
fi
done
Jak tablica się wygeneruje, to można ją przeiterować, by odczytać wszystkie elementy:
Code:
echo "Not installed RPMS:"
for i in ${MISRPMS[@]}; do
echo " $i is not installed"
done
To też działa, ale czy da się lepiej? No da się! Dodajmy więc funkcję, której przekażemy tablicę jako dane wejściowe:
Code:
function _printArray(){
ARRAY=("$@")
for i in "${ARRAY[@]}"; do
echo -e " ${i}"
done
}
Sprawdźmy, co obie tablice zebrały:
Code:
echo "# Installed RPMs:"
_printArray ${INSRPMS[@]}
echo -e "\n# Missing RPMs:"
_printArray ${MISRPMS[@]}
Działa dobrze, ale jakoś tak smutno. Dodajmy trochę kolorów - poprawi to również czytelność wyniku.
W osobnej sesji sprawdźmy, co się stanie, jak to przeklepiemy:
Code:
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'
echo -e "${RED}RED${NC}"
echo -e "${GREEN}GREEN${NC}"
Stosunkowo łatwo można pokolorować nasz wynik, tworząc nowe tablice z zainstalowanymi i brakującymi paczkami:
Code:
for i in ${RPMS[@]}; do
rpm -q --queryformat "%{NAME}\n" ${i} &> /dev/null
if [ $? -eq 0 ]; then
INSRPMS=(${INSRPMS[@]} "${GREEN}${i}${NC}")
else
MISRPMS=(${MISRPMS[@]} "${RED}${i}${NC}")
fi
done
Ma to zasadniczą wadę. Wynik na ekranie będzie, owszem, ładny, jednak tracimy możliwość dalszej obróbki nowo utworzonych tablic, bo każdy element ma taką formę:
Code:
\033[0;32mgnome-shell-lang\033[0m
Spróbujmy więc jako pierwszy element tablicy, którą przekazujemy do naszej funkcji, dodać kolor:
Code:
_printArray green ${INSRPMS[@]}
W takiej postaci pierwszym pakietem, który będzie wyszukiwany będzie nazwa koloru, dlatego poprośmy for o to, by liczył elementy w tablicy od drugiego elementu:
Wróćmy do naszego skryptu. Obslużmy przekazany pierwszy element tablicy, czyli kolor, i połączmy wszystko:
Code:
#!/bin/bash
RPMS=( TESTOWY_NIE_MA_TAKIEGO_PAKIETU nie_ma cheese-lang gdm-lang gnome-contacts-lang
gnome-control-center-color
gnome-control-center-goa gnome-control-center-lang gnome-session-lang gnome-session-wayland
gnome-shell-calendar gnome-shell-classic gnome-shell-extension-gpaste gnome-shell-lang
gnome-shell-search-provider-bijiben gnome-shell-search-provider-contacts
gnome-shell-search-provider-documents gnome-shell-search-provider-nautilus gnome-tweaks-lang
gstreamer-plugins-bad-lang libpurple-lang libpurple-tcl pidgin pulseaudio-gdm-hooks cheese
gnome-shell-extension-desktop-icons gnome-contacts gnome-tweaks libpurple patterns-gnome-gnome
patterns-gnome-gnome_imaging patterns-gnome-gnome_office patterns-gnome-gnome_utilities
libpurple-branding-openSUSE patterns-gnome-gnome_x11 gstreamer-plugins-farstream
patterns-gnome-gnome_basic libfarstream-0_2-5 patterns-gnome-gnome_basis gdm-branding-openSUSE
gdm gnome-shell gnome-session-default-session gnome-session gnome-control-center libcheese-gtk25
libcheese8 gstreamer-plugins-bad
)
INSRPMS=()
MISRPMS=()
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m'
function _printArray(){
ARRAY=("$@")
if [ $1 = "red" ]; then
COL=$RED
elif [ $1 = "green" ]; then
COL=$GREEN
fi
for i in "${ARRAY[@]:1}"; do
echo -e " ${COL}${i}${NC}"
done
}
for i in ${RPMS[@]}; do
rpm -q --queryformat "%{NAME}\n" ${i} &> /dev/null
if [ $? -eq 0 ]; then
INSRPMS=(${INSRPMS[@]} "${i}")
else
MISRPMS=(${MISRPMS[@]} "${i}")
fi
done
echo "Installed RPMs:"
_printArray green ${INSRPMS[@]}
echo -e "\nMissing RPMs:"
_printArray red ${MISRPMS[@]}
Przydatne linki: