[inizio] [indice generale] [precedente] [successivo] [indice analitico] [contributi]


267. Script per la gestione dei pacchetti software

267.1 Un sistema per gestire le installazioni tradizionali nella distribuzione Slackware

Quando si installa un programma distribuito in forma originale, quando cioè lo si deve prima compilare e poi installare nel modo previsto dall'autore, di solito non si ha la possibilità di disinstallarlo in un secondo momento.

Gli strumenti forniti dalle distribuzioni Slackware permettono di installare e disinstallare in modo spartano i programmi, purché siano rispettate certe condizioni. Quando si installa un programma che prima deve essere compilato e poi installato attraverso uno script o un file-make fatti dall'autore, non è possibile fare in modo che il meccanismo dell'installazione Slackware ne diventi consapevole.

Perché il programma installato possa essere disinstallabile attraverso gli strumenti Slackware, occorre creare per lui un file all'interno di `/var/log/packages/' contenente l'elenco dei file che lo compongono.

In questa sezione viene mostrato uno script da utilizzare per avviare le operazioni di installazione di un programma distribuito in forma normale, ovvero non nel modo previsto dalla distribuzione Slackware. Quando lo script viene avviato, memorizza la situazione del filesystem globale, quindi permette all'utente di svolgere le operazioni necessarie a compiere l'installazione e al termine confronta la nuova situazione del filesystem con quella precedente per determinare quali file siano stati aggiunti. In questo modo, viene poi aggiunta la descrizione di un nuovo pacchetto all'interno di `/var/log/packages/'. Lo script può essere utilizzato solo dall'utente `root' ed è opportuno che durante il suo funzionamento non siano in corso altre attività, soprattutto, nessun'altra applicazione deve creare dei file.

#!/bin/bash
#======================================================================
# SlackwareTrace
#======================================================================

#======================================================================
# Variabili.
#======================================================================

    #------------------------------------------------------------------
    # Nome per un file temporaneo utilizzato per ricevere le risposte
    # all'esecuzione del comando «dialog --inputbox».
    #------------------------------------------------------------------
    RISPOSTA="/tmp/risposta"
    #------------------------------------------------------------------
    # Nome per un file temporaneo contenente l'elenco dei file presenti
    # nel filesystem PRIMA.
    #------------------------------------------------------------------
    ELENCO_FILE_PRIMA="/tmp/elenco_PRIMA"
    #------------------------------------------------------------------
    # Nome per un file temporaneo contenente l'elenco dei file presenti
    # nel filesystem DOPO.
    #------------------------------------------------------------------
    ELENCO_FILE_DOPO="/tmp/elenco_DOPO"
    #------------------------------------------------------------------
    # Nome per un file temporaneo contenente l'elenco dei file aggiunti
    # nel filesystem dopo le operazioni di installazione.
    #------------------------------------------------------------------
    ELENCO_FILE_AGGIUNTI="/tmp/elenco_AGGIUNTI"
    #------------------------------------------------------------------
    # Variabile utilizzata per ricevere i comandi.
    #------------------------------------------------------------------
    COMANDO=""
    #------------------------------------------------------------------
    # Variabile utilizzata per ricevere il nome del pacchetto.
    #------------------------------------------------------------------
    PACCHETTO=""
    #------------------------------------------------------------------
    # Variabile utilizzata per ricevere la descrizione del pacchetto.
    #------------------------------------------------------------------
    DESCRIZIONE=""
    #------------------------------------------------------------------
    # Variabile utilizzata per salvare il prompt.
    #------------------------------------------------------------------
    SALVA_PROMPT=$PS1

#======================================================================
# Inizio.
#======================================================================

    #------------------------------------------------------------------
    # Verifica la quantità di argomenti.
    #------------------------------------------------------------------
    if [ $# != 0 ]
    then
echo "Questo script è completamente interattivo e quindi non \
utilizza alcun argomento."
exit 1
    fi
    #------------------------------------------------------------------
    # Verifica che l'utente sia 'root'.
    #------------------------------------------------------------------
    if [ $UID != 0 ]
    then
echo "Questo script può essere utilizzato solo dall'utente \
'root'."
exit 1
    fi
    #------------------------------------------------------------------
    # Salva la situazione del filesystem PRIMA.
    # Sono esclusi i percorsi «/tmp», «/proc» e «/mnt».
    #------------------------------------------------------------------
    reset
    echo "---------------------------------------------------"
    echo "È in corso la scansione del filesystem per "
    echo "determinare la situazione iniziale dei file esistenti."
    echo ""
    echo "Attendere prego..."
    echo "---------------------------------------------------"
    find \
/ -path "/proc" -prune -o -path "/tmp" -prune -o -path "/mnt" -prune \
-o -print | sort > $ELENCO_FILE_PRIMA
    #------------------------------------------------------------------
    # Avvia una subshell per l'esecuzione dei comandi necessari
    # all'installazione. Si comincia dall'avvisare l'utente.
    #------------------------------------------------------------------
    reset
    dialog --msgbox \
"Attenzione! Sta per essere avviata una subshell per\
\n\
l'esecuzione dei comandi necessari all'installazione\
\n\
del software.\
\n\
Di solito si tratta di eseguire qualcosa di molto simile\
\n\
a 'make install'.\
\n\
\n\
Al termine si dovrà tornare allo script utilizzando\
\n\
il comando exit." \
18 70
    #------------------------------------------------------------------
    # Modifica il prompt.
    #------------------------------------------------------------------
    PS1=\
"Eseguire i comandi necessari a compiere l'installazione \
quindi utilizzare il comando exit per tornare allo script.\
\n\
$0>"
    export PS1
    #------------------------------------------------------------------
    # Avvia la subshell.
    #------------------------------------------------------------------
    /bin/sh
    #------------------------------------------------------------------
    # Ripristina il prompt.
    #------------------------------------------------------------------
    PS1=$SALVA_PROMPT
    export PS1
    #------------------------------------------------------------------
    # Salva la situazione del filesystem DOPO.
    # Sono esclusi i percorsi «/tmp», «/proc» e «/mnt».
    #------------------------------------------------------------------
    reset
    echo "---------------------------------------------------"
    echo "È in corso la scansione del filesystem per "
    echo "determinare la nuova situazione dei file esistenti."
    echo ""
    echo "Attendere prego..."
    echo "---------------------------------------------------"
    find \
/ -path "/proc" -prune -o -path "/tmp" -prune -o -path "/mnt" -prune \
-print | sort > $ELENCO_FILE_DOPO
    #------------------------------------------------------------------
    # Confronta i due file ed emette solo le righe del secondo elenco
    # che non appaiono nel primo.
    # Salva il risultato in un altro file temporaneo.
    #------------------------------------------------------------------
    comm -13 \
$ELENCO_FILE_PRIMA $ELENCO_FILE_DOPO > $ELENCO_FILE_AGGIUNTI
    #------------------------------------------------------------------
    # Verifica che il file generato non sia vuoto.
    #------------------------------------------------------------------
    if [ -z "`cat $ELENCO_FILE_AGGIUNTI`" ]
    then
#--------------------------------------------------------------
# Non ha trovato alcun file in più rispetto alla
# situazione precedente. Lo script avvisa e termina.
#--------------------------------------------------------------
reset
dialog --msgbox \
"Non è stato aggiunto alcun file.\
\n\
Non verrà fatta alcuna registrazione di questa installazione." \
7 70
exit 2
    fi
    #------------------------------------------------------------------
    # Richiede il nome del pacchetto.
    #------------------------------------------------------------------
    while [ 0 ]                                               # FOREVER
    do
reset
dialog --inputbox \
"Inserisci il nome da usare per identificare questo pacchetto.\
\n\
Per seguire la convenzione usata dalla procedura di installazione\
\n\
Slackware, si possono usare solo otto caratteri.\
\n\
Il nome del pacchetto servirà per creare un file contenere le\
\n\
informazioni sul pacchetto, di conseguenza, occorre rispettare le\
\n\
regole per i nomi dei file.\
\n\
\n\
\n\
<Ok> prosegue,\
\n\
<Cancel> ripete la richiesta." \
17 70 2> $RISPOSTA
#--------------------------------------------------------------
# Controlla la risposta data dall'utente.
#--------------------------------------------------------------
if [ $? = 0 ]
then
    #----------------------------------------------------------
    # La risposta è stata un OK e quindi prosegue.
    #----------------------------------------------------------
    PACCHETTO=`cat $RISPOSTA`
else
    #----------------------------------------------------------
    # La risposta è stata un CANCEL e quindi ripete il loop.
    #----------------------------------------------------------
    continue
fi
#--------------------------------------------------------------
# Controlla che il nome non sia già utilizzato.
#--------------------------------------------------------------
if [ -e "/var/log/packages/$PACCHETTO" ]
then
    #----------------------------------------------------------
    # Il nome esiste già. Ripete il loop.
    #----------------------------------------------------------
    reset
    dialog --msgbox \
"Attenzione! il nome $PACCHETTO è già stato usato.\
\n\
Se ne deve inserire un altro."\
6 70
    continue
fi
#--------------------------------------------------------------
# Controlla che il nome sia accettabile tentando di creare
# un file con quello.
#--------------------------------------------------------------
rm "/tmp/$PACCHETTO"
echo "prova" > "/tmp/$PACCHETTO"
#--------------------------------------------------------------
# Se è riuscito a creare il file, tutto dovrebbe
# essere in ordine.
#--------------------------------------------------------------
if [ -e "/tmp/$PACCHETTO" ]
then
    #----------------------------------------------------------
    # Il nome è valido.
    #----------------------------------------------------------
    echo "ok" > /dev/null
else
    #----------------------------------------------------------
    # Il nome non è valido. Ripete il loop.
    #----------------------------------------------------------
    reset
    dialog --msgbox \
"Attenzione! il nome $PACCHETTO non è valido.\
\n\
Se ne deve inserire un altro." \
7 70
    continue
fi
#--------------------------------------------------------------
# Se sono stati superati tutti gli ostacoli, il loop viene
# interrotto.
#--------------------------------------------------------------
break
    done
    #------------------------------------------------------------------
    # Finalmente è stato inserito il nome del pacchetto.
    # Si passa ora alla sua descrizione.
    #------------------------------------------------------------------
    while [ 0 ]                                               # FOREVER
    do
reset
dialog --inputbox \
"Inserisci una breve descrizione del pacchetto.\
\n\
\n\
\n\
<Ok> prosegue,\
\n\
<Cancel> ripete la richiesta." \
12 70 2> $RISPOSTA
#--------------------------------------------------------------
# Controlla la risposta data dall'utente.
#--------------------------------------------------------------
if [ $? = 0 ]
then
    #----------------------------------------------------------
    # La risposta è stata un OK e quindi prosegue.
    #----------------------------------------------------------
    DESCRIZIONE=`cat $RISPOSTA`
else
    #----------------------------------------------------------
    # La risposta è stata un CANCEL e quindi ripete il loop.
    #----------------------------------------------------------
    continue
fi
#--------------------------------------------------------------
# Se sono stati superati tutti gli ostacoli, il loop viene
# interrotto.
#--------------------------------------------------------------
break
    done
    #------------------------------------------------------------------
    # Scrive il file del pacchetto.
    #------------------------------------------------------------------
    echo "PACKAGE NAME:     $PACCHETTO" > /var/log/packages/$PACCHETTO
    echo "COMPRESSED PACKAGE SIZE:" >> /var/log/packages/$PACCHETTO
    echo "UNCOMPRESSED PACKAGE SIZE:" >> /var/log/packages/$PACCHETTO
    echo "PACKAGE LOCATION:" >> /var/log/packages/$PACCHETTO
    echo "PACKAGE DESCRIPTION:" >> /var/log/packages/$PACCHETTO
    echo "$PACCHETTO: $DESCRIZIONE" >> /var/log/packages/$PACCHETTO
    echo "$PACCHETTO:" >> /var/log/packages/$PACCHETTO
    echo "$PACCHETTO:" >> /var/log/packages/$PACCHETTO
    echo "$PACCHETTO:" >> /var/log/packages/$PACCHETTO
    echo "$PACCHETTO:" >> /var/log/packages/$PACCHETTO
    echo "$PACCHETTO:" >> /var/log/packages/$PACCHETTO
    echo "$PACCHETTO:" >> /var/log/packages/$PACCHETTO
    echo "FILE LIST:" >> /var/log/packages/$PACCHETTO
    cat $ELENCO_FILE_AGGIUNTI >> /var/log/packages/$PACCHETTO
    #------------------------------------------------------------------
    # Avvisa l'utente della conclusione dell'operazione.
    #------------------------------------------------------------------
    reset
    dialog --msgbox \
"La registrazione del pacchetto $PACCHETTO è terminata." \
5 70

#======================================================================
# Fine.
#======================================================================

Prima di poter eseguire uno script è importante attribuirgli i permessi di esecuzione necessari.

chmod +x <nome-del-file>

267.2 Fare da sé

Quando si utilizza una distribuzione GNU/Linux ben organizzata è un peccato pasticciarla con programmi o altri file installati nel modo tradizionale (`make install'). In questa sezione si propone un semplice script fatto per tenere traccia di queste installazioni.

Quando lo script viene avviato, memorizza la situazione del filesystem, quindi permette all'utente di svolgere le operazioni necessarie a compiere l'installazione e al termine confronta la nuova situazione del filesystem con quella precedente per determinare quali file siano stati aggiunti. In questo modo, viene poi aggiunta la descrizione di un nuovo pacchetto all'interno di `/var/state/mypackages/'. Lo script può essere utilizzato solo dall'utente `root' ed è opportuno che durante il suo utilizzo non siano in corso altre attività, soprattutto, nessun'altra applicazione deve creare dei file.

#!/bin/bash
#======================================================================
# traccia
#======================================================================

#======================================================================
# Variabili.
#======================================================================

    #------------------------------------------------------------------
    # Nome per un file temporaneo utilizzato per ricevere le risposte
    # all'esecuzione del comando «dialog --inputbox».
    #------------------------------------------------------------------
    RISPOSTA="/tmp/risposta"
    #------------------------------------------------------------------
    # Nome per un file temporaneo contenente l'elenco dei file presenti
    # nel filesystem PRIMA.
    #------------------------------------------------------------------
    ELENCO_FILE_PRIMA="/tmp/elenco_PRIMA"
    #------------------------------------------------------------------
    # Nome per un file temporaneo contenente l'elenco dei file presenti
    # nel file system DOPO.
    #------------------------------------------------------------------
    ELENCO_FILE_DOPO="/tmp/elenco_DOPO"
    #------------------------------------------------------------------
    # Nome per un file temporaneo contenente l'elenco dei file aggiunti
    # nel filesystem dopo le operazioni di installazione.
    #------------------------------------------------------------------
    ELENCO_FILE_AGGIUNTI="/tmp/elenco_AGGIUNTI"
    #------------------------------------------------------------------
    # Variabile utilizzata per ricevere i comandi.
    #------------------------------------------------------------------
    COMANDO=""
    #------------------------------------------------------------------
    # Variabile utilizzata per ricevere il nome del pacchetto.
    #------------------------------------------------------------------
    PACCHETTO=""
    #------------------------------------------------------------------
    # Variabile utilizzata per ricevere la descrizione del pacchetto.
    #------------------------------------------------------------------
    DESCRIZIONE=""
    #------------------------------------------------------------------
    # Variabile utilizzata per salvare il prompt.
    #------------------------------------------------------------------
    SALVA_PROMPT=$PS1

#======================================================================
# Inizio.
#======================================================================

    #------------------------------------------------------------------
    # Verifica la quantità di argomenti.
    #------------------------------------------------------------------
    if [ $# != 0 ]
    then
        dialog --msgbox \
"Questo script è completamente interattivo e quindi non \
\n\
utilizza alcun argomento." \
6 70
        exit 1
    fi
    #------------------------------------------------------------------
    # Verifica che l'utente sia 'root'.
    #------------------------------------------------------------------
    if [ $UID != 0 ]
    then
        dialog --msgbox \
"Questo script può essere utilizzato solo dall'utente \
\n\
'root'." \
6 70
        exit 1
    fi
    #------------------------------------------------------------------
    # Salva la situazione del filesystem PRIMA.
    # Sono esclusi i percorsi «/tmp», «/proc» e «/mnt».
    #------------------------------------------------------------------
    reset
        dialog --infobox \
"È in corso la scansione del filesystem per \
\n\
determinare la situazione iniziale dei file esistenti. \
\n\
\n\
Attendere prego... \
" \
6 70
    find \
/ -path "/proc" -prune -o -path "/tmp" -prune -o -path "/mnt" -prune \
-o -print | sort > $ELENCO_FILE_PRIMA
    #------------------------------------------------------------------
    # Avvia una subshell per l'esecuzione dei comandi necessari
    # all'installazione. Si comincia dall'avvisare l'utente.
    #------------------------------------------------------------------
    reset
    dialog --msgbox \
"Attenzione! Sta per essere avviata una subshell per\
\n\
l'esecuzione dei comandi necessari all'installazione\
\n\
del software.\
\n\
Di solito si tratta di eseguire qualcosa di molto simile\
\n\
a 'make install'.\
\n\
\n\
Al termine si dovrà tornare allo script utilizzando\
\n\
il comando exit." \
12 70
    #------------------------------------------------------------------
    # Modifica il prompt.
    #------------------------------------------------------------------
    PS1=\
"Eseguire i comandi necessari a compiere l'installazione \
quindi utilizzare il comando exit per tornare allo script.\
\n\
\w>"
    export PS1
    #------------------------------------------------------------------
    # Avvia la subshell.
    #------------------------------------------------------------------
    /bin/sh
    #------------------------------------------------------------------
    # Ripristina il prompt.
    #------------------------------------------------------------------
    PS1=$SALVA_PROMPT
    export PS1
    #------------------------------------------------------------------
    # Salva la situazione del filesystem DOPO.
    # Sono esclusi i percorsi «/tmp», «/proc» e «/mnt».
    #------------------------------------------------------------------
    reset
        dialog --infobox \
"È in corso la scansione del filesystem per \
\n\
determinare la nuova situazione dei file esistenti. \
\n\
\n\
Attendere prego... \
" \
6 70
    find \
/ -path "/proc" -prune -o -path "/tmp" -prune -o -path "/mnt" -prune \
-o -print | sort > $ELENCO_FILE_DOPO
    #------------------------------------------------------------------
    # Confronta i due file ed emette solo le righe del secondo elenco
    # che non appaiono nel primo.
    # Salva il risultato in un altro file temporaneo.
    #------------------------------------------------------------------
    comm -13 \
$ELENCO_FILE_PRIMA $ELENCO_FILE_DOPO > $ELENCO_FILE_AGGIUNTI
    #------------------------------------------------------------------
    # Verifica che il file generato non sia vuoto.
    #------------------------------------------------------------------
    if [ -z "`cat $ELENCO_FILE_AGGIUNTI`" ]
    then
        #--------------------------------------------------------------
        # Non ha trovato alcun file in più rispetto alla
        # situazione precedente. Lo script avvisa e termina.
        #--------------------------------------------------------------
        reset
        dialog --msgbox \
"Non è stato aggiunto alcun file.\
\n\
Non verrà fatta alcuna registrazione di questa installazione." \
6 70
        exit 2
    fi
    #------------------------------------------------------------------
    # Richiede il nome del pacchetto.
    #------------------------------------------------------------------
    while [ 0 ]                                               # FOREVER
    do
        reset
        dialog --inputbox \
"Inserisci il nome da usare per identificare questo pacchetto.\
\n\
\n\
Il nome del pacchetto servirà per creare un file contenere le\
\n\
informazioni sul pacchetto, di conseguenza, occorre rispettare le\
\n\
regole per i nomi dei file.\
\n\
\n\
\n\
<Ok> prosegue,\
\n\
<Cancel> ripete la richiesta." \
16 70 2> $RISPOSTA
        #--------------------------------------------------------------
        # Controlla la risposta data dall'utente.
        #--------------------------------------------------------------
        if [ $? = 0 ]
        then
            #----------------------------------------------------------
            # La risposta è stata un OK e quindi prosegue.
            #----------------------------------------------------------
            PACCHETTO=`cat $RISPOSTA`
        else
            #----------------------------------------------------------
            # La risposta è stata un CANCEL e quindi ripete il loop.
            #----------------------------------------------------------
            continue
        fi
        #--------------------------------------------------------------
        # Controlla che il nome non sia già utilizzato.
        #--------------------------------------------------------------
        if [ -e "/var/state/mypackages/$PACCHETTO" ]    
        then
            #----------------------------------------------------------
            # Il nome esiste già. Ripete il loop.
            #----------------------------------------------------------
            reset
            dialog --msgbox \
"Attenzione! il nome $PACCHETTO è già stato usato.\
\n\
Se ne deve inserire un altro." \
6 70
            continue
        fi
        #--------------------------------------------------------------
        # Controlla che il nome sia accettabile tentando di creare
        # un file con quello.
        #--------------------------------------------------------------
        rm "/tmp/$PACCHETTO"
        touch "/tmp/$PACCHETTO"
        #--------------------------------------------------------------
        # Se è riuscito a creare il file, tutto dovrebbe
        # essere in ordine.
        #--------------------------------------------------------------
        if [ -e "/tmp/$PACCHETTO" ]
        then
            #----------------------------------------------------------
            # Il nome è valido.
            #----------------------------------------------------------
            echo "ok" > /dev/null
        else
            #----------------------------------------------------------
            # Il nome non è valido. Ripete il loop.
            #----------------------------------------------------------
            reset
            dialog --msgbox \
"Attenzione! il nome $PACCHETTO non è valido.\
\n\
Se ne deve inserire un altro." \
6 70
            continue
        fi 
        #--------------------------------------------------------------
        # Se sono stati superati tutti gli ostacoli, il loop viene
        # interrotto.
        #--------------------------------------------------------------
        break
    done
    #------------------------------------------------------------------
    # Finalmente è stato inserito il nome del pacchetto.
    # Si passa ora alla sua descrizione.
    #------------------------------------------------------------------
    while [ 0 ]                                               # FOREVER
    do
        reset
        dialog --inputbox \
"Inserisci una breve descrizione del pacchetto.\
\n\
\n\
\n\
<Ok> prosegue,\
\n\
<Cancel> ripete la richiesta." \
12 70 2> $RISPOSTA
        #--------------------------------------------------------------
        # Controlla la risposta data dall'utente.
        #--------------------------------------------------------------
        if [ $? = 0 ]
        then
            #----------------------------------------------------------
            # La risposta è stata un OK e quindi prosegue.
            #----------------------------------------------------------
            DESCRIZIONE=`cat $RISPOSTA`
        else
            #----------------------------------------------------------
            # La risposta è stata un CANCEL e quindi ripete il loop.
            #----------------------------------------------------------
            continue
        fi
        #--------------------------------------------------------------
        # Se sono stati superati tutti gli ostacoli, il loop viene
        # interrotto.
        #--------------------------------------------------------------
        break
    done
    #------------------------------------------------------------------
    # Scrive i file del pacchetto.
    #------------------------------------------------------------------
    echo "$DESCRIZIONE" > /var/state/mypackages/$PACCHETTO.descr
    cat $ELENCO_FILE_AGGIUNTI > /var/state/mypackages/$PACCHETTO
    #------------------------------------------------------------------
    # Avvisa l'utente della conclusione dell'operazione.
    #------------------------------------------------------------------
    reset
    dialog --msgbox \
"La registrazione del pacchetto \
\n\
$PACCHETTO \
\n\
è terminata." \
7 70

#======================================================================
# Fine.
#======================================================================

Prima di poter eseguire uno script è importante ricordare di attribuirgli i permessi di esecuzione necessari.

chmod +x <nome-del-file>

---------------------------

Appunti Linux 2000.04.12 --- Copyright © 1997-2000 Daniele Giacomini --  daniele @ pluto.linux.it


[inizio] [indice generale] [precedente] [successivo] [indice analitico] [contributi]