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:
#!/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}
" $i
done
Działa, ale wynik nie jest posortowany. Dodajmy więc dwie puste tablice:
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:
for i in ${RPMS@]}; do
rpm -q --queryformat "%{NAME}
" $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:
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:
function _printArray(){
ARRAY=("$@")
for i in "${ARRAY@]}"; do
echo -e " ${i}"
done
}
Sprawdźmy, co obie tablice zebrały:
echo "# Installed RPMs:"
_printArray ${INSRPMS@]}
echo -e "
# 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:
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:
for i in ${RPMS[@]}; do
rpm -q --queryformat "%{NAME}
" ${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ę:
\033[0;32mgnome-shell-lang\033[0m
Spróbujmy więc jako pierwszy element tablicy, którą przekazujemy do naszej funkcji, dodać kolor:
_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:
${ARRAY@]:1}
Wróćmy do naszego skryptu. Obslużmy przekazany pierwszy element tablicy, czyli kolor, i połączmy wszystko:
#!/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}
" ${i} &> /dev/null
if $? -eq 0 ]; then
INSRPMS=(${INSRPMS@]} "${i}")
else
MISRPMS=(${MISRPMS@]} "${i}")
fi
done
echo "Installed RPMs:"
_printArray green ${INSRPMS@]}
echo -e "
Missing RPMs:"
_printArray red ${MISRPMS@]}
Przydatne linki: