Skryptologia – czy korzeń płonie?
Będzie trochę krótkich wpisów „tips & tricks” w skryptach powłoki. Nie są one jakieś pr0 czy coś, ale chcę stworzyć sobie taki mały prywatno-publiczny zasób różnych sztuczek.
Na pierwszy ogień, skrypty, które powinny być uruchamiane z sudo.
Całe zamieszanie polega na tym, że nie wszystkie skrypty powinny być uruchamiane z sudo, a z drugiej strony pamiętanie co powinno być uruchamiane, jest do mało efektywne. W dodatku czasami mamy już tego root-a przyznanego i każdorazowe wpisywanie sudo polecenie jest upierdliwe. Jak to ugryźć.
Po pierwsze należy przypomnieć sobie, że root, podobnie jak inne nazwy użytkowników, to tylko aliasy przyjazne dla interfejsów białkowych. System operuje identyfikatorami numerycznymi, a nasz korzeń ma identyfikator równy 0. Zatem uruchamiając skrypt, możemy sprawdzić, czy w ogóle uruchamiamy go jako root:
Listing 1. Proste sprawdzenie, czy jesteśmy root-em
#!/bin/bash
if (( $EUID != 0 )); then
echo "Spierdalaj…"
return 1
fi
Takie coś nie rozwiązuje jednak naszego problemu. Co prawda przypomina nam, że warto wklepać te dodatkowe znaczki na początku, ale nie jest to rozwiązanie globalne. Wklepywanie tego kawałka w każdym skrypcie, który tego wymaga, jest mało zabawne.
Zamknijmy zatem ten kawałek w funkcji, którą umieścimy w skrypcie startowym powłoki (zazwyczaj .bashrc, .zshrc, lub co tam w ENV macie).
Listing 2. Konar zapłonięty, w funkcji zamknięty
function make_me_sudo () {
export SUDO=''
if (( $EUID != 0 )); then
SUDO='sudo'
fi
return 0
}
# funkcja będzie dostępna globalnie
export -f make_me_sudo
Jest prawie dobrze, bo po wywołaniu tej funkcji mamy dostęp do sudo, ale czasami warto go ograniczyć. Mówiąc inaczej, chcemy posprzątać. W tym celu potrzebujemy dodatkowej funkcji, która nam to ogarnie:
Listing 3. Funkcja właściwa i funkcja sprzątająca
function make_me_sudo () {
export SUDO=''
export RESET_SUDO=0
if (( $EUID != 0 )); then
SUDO='sudo'
RESET_SUDO=1
fi
return 0
}
function unmake_me_sudo () {
if (( $RESET_SUDO !=0 )); then
$SUDO -K
fi
unset SUDO
unset RESET_SUDO
}
# funkcja będzie dostępna globalnie
export -f make_me_sudo
export -f unmake_me_sudo
I teraz mały myk. Zmienna RESET\_SUDO, przechowuje informacje o stanie początkowym. Jeżeli uruchamiając skrypt, byliśmy już root-em, wcześniej wywołaliśmy sudo, to nie zmieniamy tego stanu. Bez takiego sprawdzenia każdorazowe uruchomienie skryptu kończyłoby się zmianą stanu „świata”.
Przykład użycia poniżej
Listing 4. Przykład użycia – aktualizacja modułu jądra
#!/bin/bash
make_me_sudo
$SUDO depmod -ae
$SUDO modprobe v4l2loopback_dc
unmake_me_sudo
Tyle.