Colorare il boot di Debian

Da Guide@Debianizzati.Org.
Vai alla navigazione Vai alla ricerca
Edit-clear-history.png Attenzione. Questa guida è da considerarsi abbandonata, per via del tempo trascorso dall'ultima verifica.

Potrà essere resa obsoleta, previa segnalazione sul forum, se nessuno si propone per l'adozione.


Debian-swirl.png Versioni Compatibili

Debian 8 "jessie"

Colorare il boot di Debian

Warning.png ATTENZIONE
A partire da Debian 8 (Jessie), SysV è stato rimpiazzato di default da systemd. Per cui questa guida si considera interamente compatibile con Jessie e versioni successive, solo installando il pacchetto sysvinit-core, che comporterà la disinstallazione e il rimpiazzo di systemd.


Lo scopo di questa guida è quella di colorare i messaggi che scorrono all'avvio del sistema su una Debian-box.
Il file che si occupa della stampa a schermo dei log è /lib/lsb/init-functions, fornito dal pacchetto lsb-base, ed è quello che andremo a modificare.
Le modifiche che effettueremo non colorano solo i messaggi al boot, ma anche eventuali messaggi stampati su terminale in caso di operazioni sui servizi del sistema (ad esempio il "restart" di un demone).

Bulb.png Suggerimento
Anziché sovrascrivere il file /lib/lsb/init-functions è possibile scrivere tutte le funzioni in uno script in /lib/lsb/init-functions.d/, per esempio con nome 99-colors così da sovrascrivere per ultimo tutte le definizioni di funzione che vogliamo modificare. In questo modo le modifiche saranno persistenti anche dopo un aggiornamento. E per annullare le modifiche sarà sufficiente eliminare il file creato.

In caso invece si sia sovrascritto il file /lib/lsb/init-functions, per annullare le modifiche basta reinstallare il pacchetto lsb-base:

# apt-get --reinstall install lsb-base


Funzionamento di init-functions

Qualsiasi comportamento degli script di init del sistema, in ambiente shell, è specificato dal file init-functions. Esso contiene varie funzioni richiamate dagli init-script e si occupa di determinare lo status e l'identificazione del processo in corso per poi rilasciare dei log delle operazioni.
Le sezioni fondamentali del file sono:

log_success_msg
''Scrive un messaggio corretta esecuzione di un processo.''

log_warning_msg
''Scrive un messaggio di warning.''

log_failure_msg
''Scrive un messaggio di errore.''

log_begin_msg
log_daemon_msg
log_progress_msg
log_end_msg
log_action_msg
log_action_begin_msg
log_action_cont_msg
log_action_end_msg

Prima di iniziare è bene conoscere alcune caratteristiche del comando echo, la cui funzione è quella di mostrare a schermo righe di testo.
In Bash bisogna distinguere due tipi di comandi.

  • Comandi esterni: comandi presi con path assoluto, che fanno parte del sistema operativo e che, di solito, generano un processo separato (forking). Ad esempio:
/bin/echo
  • Comandi builtin: comandi appartenenti alla serie degli strumenti Bash, e incorporati in essa. Sono usati per aumentarne l'efficienza, in quanto assolvono più rapidamente al loro compito, e perché particolari builtin necessitano di un accesso diretto alle parti interne della shell. Ad esempio:
echo

Un builtin può avere un nome identico a quello di un comando di sistema. In questo caso Bash lo reimplementa internamente. Per esempio, il comando Bash "echo" non è uguale a "/bin/echo", sebbene la loro azione sia quasi identica. Nel nostro caso, per sfruttare in pieno le funzioni del comando echo, senza personali interpretazioni di Bash, dobbiamo usarlo come comando esterno.
Per prima cosa sostituiamo, quindi, "echo" con il path assoluto "/bin/echo/" nelle sezioni interessate del nostro file, che vedremo in seguito.
Altre caratteristiche fondamentali sono le opzioni che seguono il comando echo.

  • -n: Normalmente, ogni comando echo visualizza una nuova riga. L'opzione -n annulla questo comportamento e fa sì che il testo successivo sia stampato sulla stessa riga
  • -e: Opzione richiesta per poter visualizzare le sequenze di escape.


Le sequenze di escape sono sequenze di caratteri non stampabili che provocano particolari comportamenti della funzione "echo". I caratteri di escape non stampabili devono essere racchiusi da \033[ e m.
Le sequenze di escape che utilizzeremo nel nostro script non sono altro che sequenze di caratteri che colorano il testo che lo segue:

Nero		0;30	Grigio Scuro	1;30
Blu		0;34	Blu Chiaro	1;34
Verde		0;32	Verde Chiaro	1;32
Ciano		0;36	Ciano Chiaro	1;36
Rosso		0;31	Rosso Chiaro	1;31
Viola		0;35	Viola Chiaro	1;35
Marrone		0;33	Giallo		1;33
Grigio  	0;37	Bianco		1;37

Normal		0

La sequenza Normal si occupa di riportare il colore a quello predefinito della shell.
Se vogliamo colorare una porzione di testo è necessario inserire, prima del testo, la sequenza di escape riferita al colore voluto e, eventualmente, terminare il testo con il colore Normal affinché il testo successivo non resti colorato.

Modifica di "init-functions"

log_use_fancy_output

Per prima cosa andiamo a definire le sequenze di escape dei colori come variabili, per evitare di dover riscrivere la sequenza ogni volta nei messaggi. In più diamo la possibilità a Bash di evitare di interpretare le sequenze nel caso il nostro sistema non utilizzi la modalità fancy output, il testo colorato, nella funzione log_use_fancy_output, al fine di evitare caratteri incomprensibili nell'output.

if log_use_fancy_output; then
    BLUE='\033[1;34m'
    RED='\033[1;31m'
    YELLOW='\033[1;33m'
    GREEN='\033[1;32m'
    PINK='\033[1;35m'
    NORMAL='\033[00m'
else
    BLUE=''
    RED=''
    YELLOW=''
    GREEN=''
    PINK=''
    NORMAL=''
fi

Questa parte di codice verrà inserita dopo la sezione log_use_fancy_output, per esattezza dopo il blocco:

log_use_fancy_output () {
    TPUT=/usr/bin/tput
    EXPR=/usr/bin/expr
    if [ -t 1 ] && [ "x${TERM:-}" != "x" ] && [ "x${TERM:-}" != "xdumb" ] && [ -x $TPUT ] && [ -x $EXPR ] && $TPUT hpa 60 >/dev/null 2>&1 && $TPUT setaf 1 >/dev/null 2>&1; then
        [ -z $FANCYTTY ] && FANCYTTY=1 || true
    else
        FANCYTTY=0
    fi
    case "$FANCYTTY" in
        1|Y|yes|true)   true;;
        *)              false;;
    esac
}

Fatto ciò, nella parte successiva del file, andiamo a sostituire il comando builtin echo con il comando di sistema /bin/echo con l'aggiunta dell'opzione -e. In seguito aggiungiamo, prima e dopo la parte di testo compresa fra doppi apici che segue il comando echo, le variabili colore precedentemente definite. Le variabili definite devono essere inserite fra parentesi { } e poste dopo il simbolo del $.

${RED}

log_begin_msg

Questa funzione si occupa della parte iniziale dei messaggi relativi alle operazioni sui servizi, come il restart. Il colore utilizzato sarà il "BLUE".

log_begin_msg () {
    if [ -z "${1:-}" ]; then
        return 1
    fi

    /bin/echo -n -e "${BLUE}$@${NORMAL}"
}

log_daemon_msg

Si occupa dei messaggi sulle operazioni di avvio di servizi. Utilizzeremo il colore "BLUE" per la parte iniziale del messaggio mentre utilizzeremo il colore "PINK" per evidenziare il nome del demone su cui si opera.

log_daemon_msg () {

    if [ -z "${1:-}" ]; then
        return 1
    fi
    if [ -z "${2:-}" ]; then
        /bin/echo -n -e "${BLUE}$1:${NORMAL}"
        return
    fi
    
    /bin/echo -n -e "${BLUE}$1:${PINK} $2${NORMAL}"
}

log_progress_msg

Stampa il nome del servizio su cui sta operando. Utilizzeremo il "PINK":

log_progress_msg () {

    if [ -z "${1:-}" ]; then
        return 1
    fi
    /bin/echo -n -e " ${PINK}$@${NORMAL}"
}

log_end_msg

Lasceremo i colori "YELLOW" e "RED" rispettivamente per i messaggi di warning e fail. Aggiungeremo poi il colore "GREEN" per i messaggi di corretta esecuzione del processo. In più aggiungeremo il testo "done" prima del "." come conferma di esecuzione.
Modifichiamo questa sezione come segue (stando attenti a non ridefinire le variabili "colore" essendo esse già state definite in precedenza):

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

    retval=$1

    # Only do the fancy stuff if we have an appropriate terminal
    # and if /usr is already mounted

    if [ $1 -eq 0 ]; then
        /bin/echo -e " ${GREEN}done.${NORMAL}"
    elif [ $1 -eq 255 ]; then
        /bin/echo -e " ${YELLOW}(warning!).${NORMAL}"
    else
        /bin/echo -e " ${RED}failed!${NORMAL}"
    fi
    return $retval
}

log_action_msg

Questa funzione e le successive stampano le varie azioni compiute sui demoni. Modifichiamo questa sezione come segue:

log_action_msg () {

    /bin/echo -e "${GREEN}$@.${NORMAL}"

}

log_action_begin_msg () {

    /bin/echo -n -e "${BLUE}$@...${NORMAL}"
}

log_action_cont_msg () {

    /bin/echo -n -e "${PINK}$@...${NORMAL}"
}

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

    if [ $1 -eq 0 ]; then
        /bin/echo -e "${GREEN}done${end}${GREEN}.${NORMAL}"
    else
        /bin/echo -e "${RED}failed${end}${RED}.${NORMAL}"
    fi
}

Una modifica di questo tipo colora tutti i messaggi stampati durante l'avvio del sistema. Alcuni init-scripts, però, hanno una propria formattazione del testo di output e questo scavalcherà le direttive di init-functions.

Una modifica meno invasiva

Un altro tipo di modifica, meno invasiva, colora solo delle parti specifiche dei messaggi. In questo caso lasceremo la parte iniziale dei messaggi con il colore predefinito di Bash, mentre coloriamo utilizzando i colori "BLUE" e "GREEN" per colorare rispettivamente il nome del servizio in causa e il risultato dell'operazione. Ad esempio:

Starting GNOME Login Manager: gdm done.

Le parti interessate alla modifica saranno:

log_daemon_msg () {

    if [ -z "${1:-}" ]; then
        return 1
    fi

    if [ -z "${2:-}" ]; then
        /bin/echo -n "$1:"
        return
    fi
    
    /bin/echo -n -e "$1:${BLUE} $2${NORMAL}"
}
log_progress_msg () {

    if [ -z "${1:-}" ]; then
        return 1
    fi
    /bin/echo -n -e " ${BLUE}$@${NORMAL}"
}
log_end_msg () {
    # If no arguments were passed, return
    if [ -z "${1:-}" ]; then
        return 1
    fi

    retval=$1

    # Only do the fancy stuff if we have an appropriate terminal
    # and if /usr is already mounted

    if [ $1 -eq 0 ]; then
        /bin/echo -e " ${GREEN}done.${NORMAL}"
    elif [ $1 -eq 255 ]; then
        /bin/echo -e " ${YELLOW}(warning!).${NORMAL}"
    else
        /bin/echo -e " ${RED}failed!${NORMAL}"
    fi
    return $retval
}
log_action_cont_msg () {

    /bin/echo -n -e "${BLUE}$@...${NORMAL}"
}
log_action_end_msg () {
    if [ -z "${2:-}" ]; then
        end=""
    else
        end=" ${BLUE}($2)${NORMAL}"
    fi

    if [ $1 -eq 0 ]; then
        /bin/echo -e " ${GREEN}done${end}${GREEN}.${NORMAL}"
    else
        /bin/echo -e "${RED}failed${end}${RED}.${NORMAL}"
    fi
}




Guida scritta da: matt Swirl-auth40.png Debianized 40%
Estesa da:
Verificata da:
HAL 9000 09:32, 17 giu 2017 (CEST)

Verificare ed estendere la guida | Cos'è una guida Debianized