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.

Napisz odpowiedź

Twój adres e-mail nie zostanie opublikowany.

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax