Hlavní navigace

Debian: obarvení výstupu a přidání [ OK ]

6. 3. 2012 9:42 (aktualizováno) Petr Krčmář

Na letošním InstallFestu jsme probírali vlastnosti svých oblíbených distribucí a Debianu bylo vytknuto, že nemá pěkný barevný výstup. Naštěstí se to dá pěkně vylepšit.

Na afterparty letošního InstallFestu jsme se nějak dostali k vlastnostem různých distribucí. Od Oskara jsem se dozvěděl, že Debian je divný, protože ani při startu neukazuje, jestli všechno proběhlo v pořádku. V Gentoo to prý je a je na první pohled vidět, jestli se ten který démon nastartoval nebo ne. Debian jen chrlí výstupy a neinformuje o výsledku.

Ono je to ve skutečnosti trochu jinak. Debian tyhle věci hlásí, jen je nehlásí barevně a tak viditelně. Výchozí stav je takový, že pokud se akce povede, přidá se na konec informačního výpisu tečka. Pokud jde o delší akci běžící na pozadí bootu, napíše se „done“. Uznávám Oskarův argument, že to není sexy a už vůbec to není přehledné.

Naštěstí je možné si to jednoduše upravit. Přidám k tomu trochu teorie, pokud vás teorie nezajímá a chcete si to rovnou pořídit, přejděte na praktický postup níže.

Teoretický základ

V rámci standardizace mnoha věcí v Linuxu vznikla takzvaná Linux Standard Base (LSB), což je právě dokumentace k tomu, jak by věci měly vypadat a fungovat. Naštěstí se toho drží všechny rozumné distribuce, takže řada věcí je předvídatelných a chová se dle očekávání.

To se týká i init skriptů, které mají za úkol spouštět a vypínat systémové procesy. Důležité je, že moderní init skripty (v Debianu většina) si nedělají všechno samy, ale volají k tomu funkce, které jim systém nabízí. Tyto funkce jsou ukryty ve skriptu /lib/lsb/init-functions. Jsou tam i funkce log_end_msg() a log_action_end_msg(), které se starají o výpis finální hlášky po provedení akce, kterou má init skript udělat.

Funguje to tak, že skript na začátku spustí init-functions, čímž načte do shellu funkce z LSB. Ty pak volá pro zobrazení hlášky (třeba „Startuji Apache“) nebo právě při ukončení akce. Funkce si kontrolují, zda mají k dispozici chytrý (čti: barevný) terminál a podle toho jednoduše zapínají či vypínají podporu barev. Pokud trochu umíte shellové skripty, doporučuji skript k přečtení. Je poměrně triviální.

A teď se dostáváme k cíli: Pokud si chcete výstupy upravit, můžete tento skript zeditovat a provést změny přímo v něm. To je ale nesystémové řešení, při aktualizacích balíčků byste přišli buď o své úpravy nebo o úpravy z LSB. Naštěstí skript na konci zjišťuje, jestli existuje soubor /etc/lsb-base-logging.sh a pokud ano, zavolá ho. To je přesně naše chvíle, protože tento skript je přímo určen (čti: autoři to tak zamýšleli) tak, že si do něj uživatel dá vlastní podobu funkcí, které chce změnit v originálním souboru. Ty se samozřejmě načtením uživatelského skriptu přepíší.

Čili úkol je velmi jednoduchý: zkopírovat si zmíněné funkce log_end_msg() a log_action_end_msg() z originálního skriptu do /etc/lsb-base-logging.sh a upravit si je k obrazu svému. Můžete si je sice napsat i od nuly a velmi je zjednodušit, ale pak nebudou třeba kontrolovat zmíněný barevný terminál a zapínat barvičky jen ve správnou chvíli.

Úpravu následujícího skriptu jsem chtěl provést sám, ale nakonec jsem jednu našel na blogu Jonathana McDowella a převzal jsem ji sem. Původním autorem celého skriptu je Chris Lawrence a je uvolněn pod tříbodovou licencí BSD (viz originální skript na vašem disku).

Praktický postup

Vytvořte nový soubor /etc/lsb-base-logging.sh a zkopírujte do něj následující kód. To je vše.

# int log_end_message (int exitstatus)
log_end_msg () {
    # If no arguments were passed, return
    if [ -z "${1:-}" ]; then
        return 1
    fi

    retval=$1

    log_end_msg_pre "$@"

    # Only do the fancy stuff if we have an appropriate terminal
    # and if /usr is already mounted
    if log_use_fancy_output; then
        RED=`$TPUT setaf 1`
        GREEN=`$TPUT setaf 2`
        YELLOW=`$TPUT setaf 3`
        NORMAL=`$TPUT sgr0`
        $TPUT hpa $((`$TPUT cols` - 12))
    else
        RED=''
        GREEN=''
        YELLOW=''
        NORMAL=''
    fi

    if [ $1 -eq 0 ]; then
        /bin/echo -e " [   ${GREEN}OK${NORMAL}   ]"
    elif [ $1 -eq 255 ]; then
        /bin/echo -e " [${YELLOW}WARNING!${NORMAL}]"
    else
        /bin/echo -e " [ ${RED}FAILED${NORMAL} ]"
    fi
    log_end_msg_post "$@"
    return $retval
}

log_action_end_msg () {
    log_action_end_msg_pre "$@"
    if [ -z "${2:-}" ]; then
        end=""
    else
        end=" ($2)"
    fi

    /bin/echo -n "${end}"

    # Only do the fancy stuff if we have an appropriate terminal
    # and if /usr is already mounted
    if log_use_fancy_output; then
        RED=`$TPUT setaf 1`
        BLUE=`$TPUT setaf 4`
        NORMAL=`$TPUT sgr0`
        $TPUT hpa $((`$TPUT cols` - 12))
    else
        RED=''
        BLUE=''
        NORMAL=''
    fi


    if [ $1 -eq 0 ]; then
        /bin/echo -e " [  ${BLUE}DONE${NORMAL}  ]"
    else
        /bin/echo -e " [ ${RED}FAILED${NORMAL} ]"
    fi
    log_action_end_msg_post "$@"
}

Od této chvíle budou veškerá volání init skriptů pěkně barevná a boot vašeho Debianu bude vypadat asi takto: