Creazione automatica di un file di log per inviare quesiti al forum: differenze tra le versioni

Da Guide@Debianizzati.Org.
Vai alla navigazione Vai alla ricerca
(1.0.50)
Riga 73: Riga 73:


# Versione script
# Versione script
readonly VERSIONE="1.0.49"
readonly VERSIONE="1.0.50"


# Codename per stable e testing. Da modificare nei successivi rilasci di Debian
# Codename per stable e testing. Da modificare nei successivi rilasci di Debian
Riga 1 046: Riga 1 046:
function _extpack {
function _extpack {


  # Variabile che contiene la release attualmente utilizzata
local riga indirizzo rel linea release=""
  # Vengono tolti da sources.list eventuali spazi iniziali e tolte le righe che *non* iniziano con le stringhe
 
  # "deb http://ftp.XX.debian.org" o con
# variabile con il contenuto del file sources.list (solo righe che iniziano con deb
  # "deb ftp://ftp.XX.debian.org" o con
# e che contengono "main" )
  # "deb http://ftp2.XX.debian.org" o con
local sourceslist="$(sed -e '/^deb /!d' -e '/.* main.*/!d' /etc/apt/sources.list)"
  # "deb ftp://ftp2.XX.debian.org" e che *non* contengono un nome di release.
  # Con "cut" viene prelevato il terzo campo (la release voluta)
# variabile che contiene l'output del comando "apt-cache policy"
  local release=$(sed -r -e 's/^ *//' -e '/^deb (http|ftp):\/\/(ftp|ftp2)\...\.debian\.org.*('"$STABLE"' |stable |'"$TESTING"' |testing |sid |unstable )/!d' /etc/apt/sources.list | cut -d ' ' -f3)
local aptcachepol="$(apt-cache policy)"
 
# ciclo sulle righe della variabile "sourceslist"
while read linea; do
 
    # variabile che contiene l'URL dell'archivio (es. http://ftp.it.debian.org/debian/)
    indirizzo="$(echo "$linea" | awk '{print $2}')"
 
    # sostituisce / con \/ (necessario per il successivo sed)
    indirizzo="${indirizzo//\//\\/}"
 
    # release della riga corrente (es. wheezy o testing o sid)
    rel="$(echo "$linea" | awk '{print $3}')"
 
    # controlla che sia un nome di release valido
    if [ "$rel" = "stable" ] || [ "$rel" = "testing" ] || [ "$rel" = "unstable" ] ||
      [ "$rel" = "$STABLE" ] || [ "$rel" = "$TESTING" ] || [ "$rel" = "sid" ]; then
   
      # controlla che sia un repository di Debian
      # si basa sull'output di "apt-cache policy" e su o=Debian e l=Debian
      riga="$(echo "$aptcachepol" | sed -n '/'$indirizzo'.*'$rel'\/main.*Packages$/ {N; /.*o=Debian,.*l=Debian,/p}')"
   
      # se è un archivio valido, aggiorna la variabile "release"
        if [ ! -z "$riga" ]; then
          if [ -z "$release" ]; then
              release="$rel"
          else
              release="$(printf %b "$release\n$rel")"
          fi
        fi
    fi
done <<< "$sourceslist"


  local var="Pacchetti esterni"
local var="Pacchetti esterni"
  _prompt "$var"
_prompt "$var"
 
 
  # Lo script DEVE rilevare almeno una release. Se la variabile "release" è nulla, c'è un errore nei repository
# Lo script DEVE rilevare almeno una release. Se la variabile "release" è nulla, c'è un errore nei in "sources.list"
  # oppure lo script deve essere modificato. Questa situazione accade per indirizzi di repository
# oppure non è stato eseguito un aggiornamento della lista dei pacchetti (update)
  # non previsti (vedere il modo in cui viene ricavata la variabile "release" in alto)
# (vedere anche il modo in cui viene ricavata la variabile "release" in alto)
  if [ -z "$release" ]; then
if [ -z "$release" ]; then
     nome_e_riga "${var} all'archivio \"NON RILEVATO!\""
     nome_e_riga "${var} all'archivio \"NON RILEVATO!\""
     echo "Release non rilevata. Repository errati oppure è necessaria una modifica dello script" >> "$log" && _error
     echo "Release non rilevata. Repository errati oppure è necessaria una modifica dello script" >> "$log" && _error
     return 1
     return 1
  fi
fi


  # Numero di release trovate
# Numero di release trovate
  local num=$(echo "$release" | wc -l)
local num=$(echo "$release" | wc -l)
 
 
  # Se il numero di release è diverso da 1, la funzione termina
# Se il numero di release è diverso da 1, la funzione termina
  if [ "$num" -ne 1 ]; then
if [ "$num" -ne 1 ]; then
    nome_e_riga "$var"
    nome_e_riga "$var"
    echo "Sono presenti ${num} release in sources.list" >> "$log" && _error
    echo "Sono presenti ${num} release in sources.list" >> "$log" && _error
    return
    return
  fi
fi
 
 
  local pkg=""
local pkg=""


  # Se il numero di release è uguale a 1, la variabile pkg conterrà i pacchetti *non* facenti parte della release
# Se il numero di release è uguale a 1, la variabile pkg conterrà i pacchetti *non* facenti parte della release
  case "$release" in
case "$release" in
        "$STABLE"|stable)
    "$STABLE"|stable)
release="stable"
                    release="stable"
pkg=$(aptitude -F '%p %v %t' search '~S ~i !~Astable'  --disable-columns | column -t) ;;
                    pkg=$(aptitude -F '%p %v %t' search '~S ~i !~Astable'  --disable-columns | column -t) ;;
        "$TESTING"|testing)
    "$TESTING"|testing)
release="testing"
                    release="testing"
pkg=$(aptitude -F '%p %v %t' search '~S ~i !~Atesting'  --disable-columns | column -t) ;;
                    pkg=$(aptitude -F '%p %v %t' search '~S ~i !~Atesting'  --disable-columns | column -t) ;;
        sid|unstable)
    sid|unstable)
release="unstable"
                    release="unstable"
pkg=$(aptitude -F '%p %v %t' search '~S ~i !~Aunstable' --disable-columns | column -t) ;;
                    pkg=$(aptitude -F '%p %v %t' search '~S ~i !~Aunstable' --disable-columns | column -t) ;;
  esac
esac


  # Invia al log il contenuto di pkg (se esiste)
# Invia al log il contenuto di pkg (se esiste)
  nome_e_riga "${var} all'archivio \"${release}\""
nome_e_riga "${var} all'archivio \"${release}\""
  if [ -z "$pkg" ]; then
if [ -z "$pkg" ]; then
     echo "Nessun pacchetto esterno installato" >> "$log" && _error
     echo "Nessun pacchetto esterno installato" >> "$log" && _error
  else
else
     echo "$pkg" >> "$log" && _ok
     echo "$pkg" >> "$log" && _ok
  fi
fi
}
}


# --------------------------------------------------------------------------
# --------------------------------------------------------------------------
Riga 1 120: Riga 1 152:
== Changelog ==
== Changelog ==
<!-- Qui vanno inserite le spiegazioni di eventuali modifiche dello script (chi, cosa, quando). Ricordarsi di modificare la versione (variabile VERSIONE) all'interno del codice (la versione iniziale è 1.0.0) -->
<!-- Qui vanno inserite le spiegazioni di eventuali modifiche dello script (chi, cosa, quando). Ricordarsi di modificare la versione (variabile VERSIONE) all'interno del codice (la versione iniziale è 1.0.0) -->
;1.0.50
:''Rivista la funzione _extpack (repository Debian''
:''in base al comando "apt-cache policy"''
:[[Utente:S3v|S3v]] 22:37, 22 dic 2014 (CET)
;1.0.49
;1.0.49
:''Aggiunti trap INT e "dpkg-foreign-architectures"''
:''Aggiunti trap INT e "dpkg-foreign-architectures"''

Versione delle 21:37, 22 dic 2014

Debian-swirl.png Versioni Compatibili

Tutte le versioni supportate di Debian

Introduzione

Questo script permette la creazione di un file contenente informazioni utili che possono aiutare a comprendere meglio il proprio problema oppure che è possibile portare a conoscenza del forum per tentare di risolverlo insieme. Le informazioni riguardano i seguenti tipi di problema:

  • Connessioni di rete
  • Video
  • Audio (tramite lo script ALSA prelevabile qui)
  • Sottosistema di gestione dei pacchetti (APT)
  • Mount/unmount di periferiche
  • Touchpad
  • Altro. Verranno inserite nel log solo informazioni generiche (già presenti nei log creato con tutte le tipologie di problema precedenti).

Lo script crea due file:

log_data
contiene le informazioni in formato testo
log_data.{bz2,zip,tgz}
il file precedente ma in formato compresso. Può essere allegato ad una discussione sul forum

Se si vuole, attraverso lo script è anche possibile inviare il file direttamente a paste.debian.net per poterlo condividere pubblicamente, in questo caso il file non potrà superare la grandezza complessiva di 240K circa (diviso in parti della dimensione massima di 60K circa) e le informazioni saranno disponibili a chiunque per una settimana.
Prima di effettuare l'invio, lo script chiede un esplicito consenso all'utente.

Per usufruire del servizio offerto da paste.debian.net è necessaria l'installazione del pacchetto pastebinit:

# apt-get install pastebinit
Info.png Nota
Lo script è liberamente modificabile.
Per ogni segnalazione, informazione o suggerimento fare riferimento a questa discussione sul forum.


Utilizzo

  1. Eseguire un upgrade del sistema, se possibile, in modo che le informazioni raccolte dallo script siano aggiornate.
  2. Copiare manualmente il codice dello script in un file di testo. Il nome del file può essere scelto liberamente.
    Se si preferisce, è possibile eseguire il seguente comando:
    $ wget -q -O- "http://guide.debianizzati.org/index.php?title=Creazione_automatica_di_un_file_di_log_per_inviare_quesiti_al_forum&action=edit" | sed -n "/^== Script/{n;:a n; /^&lt/ ! {s/\&amp;/\&/g; p; ba}}" > nomefile
    Questo creerà il file di testo "nomefile" contenente lo script.
    Si presuppone che non esista nella directory corrente un file avente lo stesso nome (altrimenti verrà sovrascritto), che il pacchetto "wget" sia installato e che, ovviamente, la connessione alla Rete sia funzionante.
  3. Dare i permessi di esecuzione al file appena creato. Supponendo che si chiami nomefile:
    $ chmod +x nomefile
  4. Eseguire lo script con i permessi di root:
    # ./nomefile
    il comando precedente deve essere eseguito nella stessa directory in cui risiede lo script.
    L'utilizzo dei permessi di root è motivato dal fatto che alcuni comandi devono essere eseguiti necessariamente come utente privilegiato.
  5. Leggere le informazioni a video.

Parametri dello script

Lo script accetta, in maniera facoltativa, alcuni parametri:

--tipo={rete|video|audio|apt|mount|touchpad|generico}
specifica il tipo di problema
Es: --tipo=apt
--nocompress
non crea il file compresso del file di log
--nopaste
non invia il file di log a paste.debian.net
--help
visualizza informazioni sull'utilizzo dei parametri

Script

#! /bin/bash

# --------------------------------------------------------------------------
# Impostazioni
# --------------------------------------------------------------------------

# I file creati saranno leggibili e scrivibili da tutti
umask 0011

# Intercettazione Ctrl+C
trap _exit INT

# --------------------------------------------------------------------------
# Funzioni che sovrascrivono comandi
# --------------------------------------------------------------------------

# Rimpiazza echo ed echo -n, impedendo echo -e e le possibili combinazioni
# Sintassi accettata:
#  echo -n "testo"  # stampa senza a capo finale
#  echo "testo"     # stampa con a capo finale
#  echo             # stampa una riga vuota
function echo {
  if [ $# -gt 1 ] && [ "$1" = "-n" ]; then
    shift
    printf %s "$*"
  else
    printf %s\\n "$*"
  fi
}

# --------------------------------------------------------------------------
# Costanti
# --------------------------------------------------------------------------

# Versione script
readonly VERSIONE="1.0.50"

# Codename per stable e testing. Da modificare nei successivi rilasci di Debian
readonly STABLE="wheezy"
readonly TESTING="jessie"

# Path dei comandi dello script
readonly PATH="/bin:/sbin:/usr/bin:/usr/sbin"

# Nome del file di log in base alla data corrente
readonly log="log_$(date '+%d%b_%H%M%S')"

# Nome del file compresso. Viene usata l'estensione .bz2 a meno
# che non venga modificata da _compress
complog="${log}.bz2"

# nome utente
utente=$(logname) &&
[ "$utente" != "root" ] || {
  utente=
  tmputente=
  for tmputente in $(users); do
    if [ "$tmputente" = "root" ]; then
      continue
    elif [ -z "$utente" ]; then
      utente=$tmputente
    elif [ "$utente" != "$tmputente" ]; then
      utente=
      break
    fi
  done
  if [ -z "$utente" ]; then
    # NOTA: "root" è permesso (solo) se scelto esplicitamente dall'utente
    echo -n "Inserisci il tuo nome utente: "
    read tmputente &&
    # non può contenere: spazi, tabulazioni, nuove righe; né essere vuota
    [ -n "${tmputente##*[[:space:]]*}" ] &&
    # l'utente deve aver effettuato il login (anche in altre console)
    case " $(users) " in
      *" ${tmputente} "* ) true
                           ;;
      * ) false
          ;;
    esac || {
      echo "Nome utente invalido o non ha effettuato il login!" >&2
      exit 255
    }
    utente=$tmputente
  fi
  unset tmputente
}
readonly utente

# nome host
readonly nomehost=$(hostname)

# Codici stile carattere
readonly ROSSO="\033[01;31m" 	# colore rosso e grassetto
readonly VERDE="\033[01;32m" 	# colore verde e grassetto
readonly BOLD="\033[01m"        # grassetto
readonly FINE="\033[0m"         # reset

# --------------------------------------------------------------------------
# Sezione relativa ai parametri dello script
# --------------------------------------------------------------------------

# Funzione che segnala un errato utilizzo dei parametri e termina lo script
function _parm_err {
  echo "Parametri non validi" && _parm_uso
}

# Messaggio di errore se viene specificato più di un tipo di problema attraverso
# i parametri.
function _parm_tipo_err {
  echo "È possibile specificare un solo di tipo di problema" && _parm_uso
}

# Messaggio visualizzato nel caso in cui venga specificato lo stesso parametro
function _parm_rip_err {
  echo "È stato immesso lo stesso parametro" && _parm_uso
}

# Messaggio visualizzato nel caso in cui --help non sia l'unico parametro specificato
function _parm_uso_err {
  echo "Il parametro --help non deve essere accompagnato da altri parametri" && _parm_uso
}

# Funzione che stampa informazioni sull'utilizzo dei parametri
function _parm_uso {
  printf %b "
Utilizzo dei parametri:

$BOLD--tipo={rete|video|audio|apt|mount|touchpad|generico}$FINE
  utilizzato per specificare un solo tipo di problema.
  Es: --tipo=apt
  
$BOLD--nocompress$FINE
  non viene creato un file compresso del log
  
$BOLD--nopaste$FINE
  non viene inviato il log a paste.debian.net
  
$BOLD--help$FINE
  visualizza queste informazioni
  
"  && exit
}

# Inizializzazione di variabili. La variabile TIPO serve ad evitare ripetizioni
# nel passaggio del parametro tipo=blabla
NOCOMPRESS=0 NOPASTE=0 TIPO=0 TIPO_RETE=0 TIPO_APT=0 TIPO_VIDEO=0
TIPO_AUDIO=0 TIPO_MNT=0 TIPO_TOUCH=0 TIPO_COMM=0

while [ $# -gt 0 ] ; do
  case "$1" in
    "--nocompress") 	[ "$NOCOMPRESS" -eq 1 ] && _parm_rip_err || NOCOMPRESS=1      ;;
    "--nopaste")	[ "$NOPASTE" -eq 1 ] && _parm_rip_err || NOPASTE=1	      ;;
    "--tipo=rete")	[ "$TIPO" -eq 1 ] && _parm_tipo_err || TIPO=1 && TIPO_RETE=1  ;;
    "--tipo=apt")	[ "$TIPO" -eq 1 ] && _parm_tipo_err || TIPO=1 && TIPO_APT=1   ;;
    "--tipo=video")	[ "$TIPO" -eq 1 ] && _parm_tipo_err || TIPO=1 && TIPO_VIDEO=1 ;;
    "--tipo=audio")	[ "$TIPO" -eq 1 ] && _parm_tipo_err || TIPO=1 && TIPO_AUDIO=1 ;;
    "--tipo=mount")	[ "$TIPO" -eq 1 ] && _parm_tipo_err || TIPO=1 && TIPO_MNT=1   ;;
    "--tipo=touchpad")	[ "$TIPO" -eq 1 ] && _parm_tipo_err || TIPO=1 && TIPO_TOUCH=1 ;;
    "--tipo=generico")	[ "$TIPO" -eq 1 ] && _parm_tipo_err || TIPO=1 && TIPO_COMM=1  ;;
    "--help")		[ $BASH_ARGC -gt 1 ] && _parm_uso_err || _parm_uso            ;;
    *)			_parm_err
  esac
  shift
done

# --------------------------------------------------------------------------
# Funzioni iniziali
# --------------------------------------------------------------------------

# Funzione che stampa il messaggio introduttivo
function _intro {
 echo "
*********************************************************************************
*  www.debianizzati.org                                                         *
*                                                                               *
*  Script che crea un log utile alla risoluzione dei problemi più comuni        *
*  Versione "$VERSIONE"                                                              *
*                                                                               *
*********************************************************************************"
}

# Funzione che stampa alcune avvertenze sullo script
function _avvertenze {
  local risp
  echo "
-- Lo script richiede i permessi di root per essere eseguito
-- Per inviare il log su paste.debian.net è necessario il pacchetto 'pastebinit'
-- L'invio del log a paste.debian.net avverrà solo dopo esplicito consenso
-- Verrà creato un file contenente l'output di questo script
-- Verrà creato un file in formato compresso da inviare al forum"
  echo -n "Continuare [S/n]? "
  read risp || risp="ERROR"
  
  # Se non viene premuto "s" o "S" o [Invio], lo script termina
  [ -z "$risp" ] || [ "$risp" = "s" ] || [ "$risp" = "S" ] || _exit
}

# Funzione che esegue un check preliminare
function _check {
  if [ $EUID -ne 0 ]; then # Lo script viene lanciato da root?
    echo "Lo script deve essere lanciato da root" && _exit
  fi
 
  # Se esiste già un file di log con lo stesso nome oppure file compressi con lo
  # stesso nome di quelli che verranno creati, lo script chiede se cancellarli o meno
  local risp
  if [ -f "$log" ] || [ -f "${log}.zip" ] || [ -f "${log}.bz2" ] || [ -f "${log}.tgz" ]; then
    echo $'\n'"Esiste già un file ${log}, ${log}.zip, ${log}.bz2 o ${log}.tgz nella directory corrente."
    echo -n "Sovrascivere [S/n]? "
    read risp
    case "$risp" in
      ""|[Ss]) rm -f -- "$log" "${log}.zip" "${log}.bz2" "${log}.tgz"  ;;
      *)       _exit
    esac
  fi
}

# --------------------------------------------------------------------------
# Funzioni per l'invio del log a paste.debian.net
# --------------------------------------------------------------------------

# Funzione per separare il log in parti per l'invio a paste.debian.net
function _split_and_send {  
  local paste_url='http://paste.debian.net'
  local chunk_prefix='pastebin'
  local chunk_num=1
  local paste_exit_status=0
  local chunkfile pastelink
 
  # dimensione massima del singolo file da inviare
  local chunk_size='60k'

  # termina la funzione se il log è più grande di chunk_size x 4 (numero di parti impostate)
  if [ "$(du -k "$log" | cut -f1)" -gt 240 ]; then
     echo "Log troppo grande per essere inviato a paste.debian.net"
     echo "Allegare il file compresso alla discussione sul forum."
     return 1
  fi
 
  # rinomina parti di log preesistenti (se ve ne sono)
  # scarta i messaggi di errore (se presenti)
  rename "s/${chunk_prefix}/old-${chunk_prefix}-$(date '+%s')/" "$chunk_prefix".* > /dev/null 2>&1
 
  # dividi il file di log in parti di $chunk_size bytes senza spezzare le linee
  # scarta i messaggi di errore (se presenti) per log di dimensione superiore a 10 parti
  # (max 10 parti con l'opzione -a)
  split -a 1 -d -C "$chunk_size" "$log" "${chunk_prefix}." > /dev/null 2>&1
 
  # comunica il numero di parti inviate
  chunk_num=$(find . -maxdepth 1 -type f -name "${chunk_prefix}.*" -printf x |
              wc -c)
  if [ "$chunk_num" = 1 ]; then
      echo $'\nIl log sarà inviato in un singolo file.'
  else
      echo $'\n'"Il log sarà inviato in ${chunk_num} parti."
  fi
 
  # invia al massimo 4 parti
  echo $'\nIl log è consultabile ai seguenti indirizzi:'
  for chunkfile in "${chunk_prefix}."[0-3]; do
 
    # verifica l'esistenza del file da inviare
    if [ -f "$chunkfile" ]; then

    # invia dati tramite pastebinit, l'output d'errore viene soppresso
    pastelink=$(pastebinit -a '' -b "$paste_url" -i "$chunkfile" 2>/dev/null)
     
      if [ $? = 0 ]; then
	  # invio apparentemente riuscito (pastebinit exit status = 0)
      
	  # controlla URL restituita da pastebinit
	  case "$pastelink" in
	  # verifica in caso di url corretta
	  "$paste_url"/[0-9]*)
	      echo ".. inviato ${chunkfile} all'indirizzo ${pastelink}"
	      ;;
	  # verifica in caso di url non corretta
	  *)
	      echo ".. ${paste_url} ha restituito una URL non valida (${pastelink}) per ${chunkfile}!"
	      paste_exit_status=1
	  esac
  
      else
	  # Invio fallito (pastebinit exit status = 1)
	  echo ".. non riuscito invio ${chunkfile}"
	  paste_exit_status=1
      fi
 
    fi
 
  done
 
  # cancella le parti di log inviate
  for chunkfile in "./${chunk_prefix}."[0-9]*; do
    if [ -f "$chunkfile" ]; then
      rm -f -- "$chunkfile"
    fi
  done
 
  return $paste_exit_status
}

# Funzione che invia il log a paste.debian.net
function _upload {
  # Nessun invio a paste.debian.net se viene scelto "--nopaste"
  [ "$NOPASTE" -eq 1 ] && return
  
  local risp
  # Pastebinit è installato?
  if [ ! -f /usr/bin/pastebinit ]; then
    echo $'\nNon è possibile inviare il log a paste.debian.net\nIl pacchetto "pastebinit" non è installato.'
    return 1
  fi
  # Invia il file log.txt a paste.debian.net
  echo -n $'\nInviare il log a http://paste.debian.net [S/n]? '
  read risp
  case "$risp" in
    ""|[Ss])
      _split_and_send
      if [ $? = 0 ]; then
        echo $'\nIl log è stato inviato'
      else
        echo $'\nSi sono verificati errori nell\'invio del log!'
      fi
      ;;
    *)
      echo "Il log non è stato inviato"
  esac
}

# --------------------------------------------------------------------------
# Funzioni di creazione del file compresso e messaggi di successo/fallimento
# --------------------------------------------------------------------------

# Funzione richiamata in caso di corretta/scorretta creazione del file compresso
function _compress_ok { echo "File compresso creato correttamente nella directory corrente."; }

function _compress_err { echo "Errore nella creazione del file compresso."; }

# Funzione che crea il file compresso
# Prova a creare nell'ordine: un file .bz2, un file .zip o un file .tgz
function _compress {
  # La funzione termina se è stato utilizzato il parametro "--nocompress"
  [ "$NOCOMPRESS" -eq 1 ] && return

  local risp
  echo -n $'\nCreare un file compresso [S/n]? '
  read risp
  case "$risp" in
    ""|[Ss])
      echo "Sta per essere creato un file compresso..."
      sleep 1
      if [ -f /bin/bzip2 ]; then
        bzip2 -k9 "$log" && _compress_ok || _compress_err
      elif [ -f /usr/bin/zip ]; then
        zip "${log}.zip" "$log" && _compress_ok || _compress_err
        complog="${log}.zip"
      else
        tar czf "${log}.tgz" "$log" && _compress_ok || _compress_err
        complog="${log}.tgz"
      fi
      ;;
    *)
      echo "Non è stato creato un file compresso."
  esac
}

# --------------------------------------------------------------------------
# Funzione di stampa menù e selezione del problema
# --------------------------------------------------------------------------

function _scelta {

  # Problemi selezionati in base al parametro passato allo script
  [ "$TIPO_RETE"  -eq 1 ] && _wait && echo $'### Problemi di rete ###\n'            > "$log" && _rete   && return
  [ "$TIPO_VIDEO" -eq 1 ] && _wait && echo $'### Problemi video ###\n'              > "$log" && _video  && return
  [ "$TIPO_AUDIO" -eq 1 ] && _wait && echo $'### Problemi audio ###\n'              > "$log" && _audio  && return
  [ "$TIPO_APT"   -eq 1 ] && _wait && echo $'### Problemi APT ###\n'                > "$log" && _apt    && return
  [ "$TIPO_MNT"   -eq 1 ] && _wait && echo $'### Problemi mount-unmount ###\n'      > "$log" && _mount  && return
  [ "$TIPO_TOUCH" -eq 1 ] && _wait && echo $'### Problemi touchpad ###\n'           > "$log" && _tpad   && return
  [ "$TIPO_COMM"  -eq 1 ] && _wait && echo $'### Solo informazioni generiche ###\n' > "$log" && _common && return
  
  # La funzione presenta un menù di scelta nel caso non sia stato passato alcun parametro
  local num
 
  clear
  _intro
  echo "
Selezionare il tipo di problema per il quale verrà generato il file di log
[1] Problemi relativi alle connessioni di rete
[2] Problemi video
[3] Problemi audio
[4] Problemi di gestione dei pacchetti (APT)
[5] Problemi di mount/unmount
[6] Problemi di funzionamento del touchpad
[7] Altro tipo di problema
[0] Uscita"
 
  while true; do
    echo -n "Scegliere il numero corrispondente: "
    read num
    case "$num" in
        [1-7])	_wait   ;;& # ;;& -> va alla successiva occorrenza del carattere immesso
            1)	echo $'### Problemi di rete ###\n'            > "$log" && _rete   ;;&
            2)	echo $'### Problemi video ###\n'              > "$log" && _video  ;;&
            3)	echo $'### Problemi audio ###\n'              > "$log" && _audio  ;;&
            4)	echo $'### Problemi APT ###\n'                > "$log" && _apt    ;;&
            5)	echo $'### Problemi mount-unmount ###\n'      > "$log" && _mount  ;;&
            6)	echo $'### Problemi touchpad ###\n'           > "$log" && _tpad   ;;&
            7)	echo $'### Solo informazioni generiche ###\n' > "$log" && _common ;;&
        [1-7])	break   ;; # Termina il ciclo 'while'
            0)	_exit   ;; # È stato inserito '0' . Uscita dallo script
            *)	# Tutti gli altri caratteri. Cancella l'input immesso e ripete la domanda
		tput cuu1 # in alto di una riga
		tput ed # cancella fino alla fine dello schermo
    esac
  done
}

# --------------------------------------------------------------------------
# Funzioni varie
# --------------------------------------------------------------------------

# Funzione che stampa solo lo spazio e il nome del comando, prima di eseguirlo
function _prompt {
  echo -n "[ ]  $*"
}

# Funzione che stampa un pallino di colore verde in caso di comando con output
# Visualizza a video l'eventuale stringa passata come primo parametro ($1).
function _ok {
  echo
  tput cuu1  # in alto di una riga
  tput cuf1  # a destra di uno spazio
  # se non ci sono parametri, viene stampato solo il pallino
  if [ $# -eq 0 ]; then
    printf %b "${VERDE}•${FINE}\n" # stampa pallino e va a capo
  # se c'è un parametro, viene stampato il pallino e il parametro
  elif [ $# -eq 1 ]; then
    printf %b "${VERDE}•${FINE}"
    tput cuf 3 # a destra di tre spazi
    tput el    # cancella fino a fine riga
    printf %b "$1\n" # stampa il parametro e va a capo
  fi
}

# Funzione che stampa una pallino rosso in caso di comando privo di output
function _error {
  echo
  tput cuu1  # in alto di una riga
  tput cuf1 # a destra di uno spazio
  # se non ci sono parametri, viene stampato solo il pallino
  if [ $# -eq 0 ]; then
    printf %b "${ROSSO}•${FINE}\n" # stampa pallino e va a capo
  # se c'è un parametro, viene stampato il pallino e il parametro
  elif [ $# -eq 1 ]; then
    printf %b "${ROSSO}•${FINE}"
    tput cuf 3 # a destra di tre spazi
    tput el    # cancella fino a fine riga
    printf %b "$1\n" # stampa il parametro e va a capo
  fi
}

# Funzione che stampa in grassetto gli argomenti
function _bold {
  printf %b "$BOLD"
  echo -n "$*"
  printf %b\\n "$FINE"
}

# Funzione che invia nel file di log due righe tra le quali viene visualizzato il
# nome del comando (passato come primo parametro della funzione -> $1)
function nome_e_riga {
  echo "
******************************************
$1
******************************************" >> "$log"
}

# Funzione che stampa un messaggio di attesa e aspetta 2 secondi
function _wait {
  echo $'\nCreazione del log in corso...\n'
}

# Stampa la data corrente nel file di log
function _data {
  echo "Log creato il $(date '+%d %B %Y alle %H.%M')" >> "$log"
}

# Funzione che nasconde nel log alcune informazioni sensibili
function _hide {

 # Sostituisce il nome utente e il nome host con 'nomeutente' e 'nomehost' se diversi da [dD]ebian
 [ "$nomehost" != "Debian" ] && [ "$nomehost" != "debian" ] && sed -i -e "s/${nomehost}/nomehost/g" "$log"
 [ "$utente" != "Debian" ] && [ "$utente" != "debian" ] && sed -i -e "s/${utente}/nomeutente/g" "$log"

 # Nasconde gli ESSID gestiti attraverso Network Manager
 local var file mydir="/etc/NetworkManager/system-connections/"

 if [ -d "$mydir" ]; then # se esiste la directory /etc/NetworkManager/system-connections/ ...
    for file in "$mydir"/*; do # ciclo attraverso il contenuto della directory
       if [ -f "$file" ]; then # se l'elemento è un file...
          var=$(sed -n "s/ssid=//p" "$file") # ... var conterrà l'eventuale ESSID...
          if [ -n "$var" ]; then # ... e se è diverso dalla stringa vuota...
             sed -i "s/${var}/\*script-removed\*/g" "$log" # ... lo nasconde nel file di log
          fi
       fi
    done
 fi

 # Nasconde nel log i i nomi delle connessioni gestite da NetworkManager
 sed -i -r "s/(NetworkManager.*keyfile.*((parsing)|(read connection))).*/\1 \*script-removed\*/" "$log"
}

# Stabilisce la data dell'ultimo aggiornamento effettuato. Viene preso in
# considerazione il file /var/log/apt/history.log oppure il file /var/log/apt/history.log.1.gz
function _lastupd {
  local convdate lastdate file=/var/log/apt/history.log
  
  if [ -f "$file" ]; then
    lastdate=$(sed -n '/^Start-Date/h ; $p' "$file" | awk '{print $2}')
    # se il file history.log non contiene la data dell'ultimo aggiornamento, viene utilizzato history.log.1.gz
    [ -z "$lastdate" ] && [ -f "${file}.1.gz" ] && lastdate=$(zcat "${file}.1.gz" | sed -n '/^Start-Date/h ; $p' | awk '{print $2}')

    # variabile che contiene la data in formato "giorno mese anno"
    convdate=$(date -d "$lastdate" '+%d %B %Y')
    
    echo $'\n'"Ultimo aggiornamento del sistema: ${convdate}" >> "$log"
  fi
}

# Funzione che stampa un messaggio che indica i file creati e poi termina lo script
function _exit {
  if [ -f "$log" ]; then
    echo -n $'\nFile contenente il log dello script: '
    _bold "$log"
  else
    echo $'\nNon è stato creato un file di log'
  fi
  
  if [ -f "$complog" ]; then
    echo -n "File compresso da allegare alla discussione sul forum: "
    _bold "$complog"
  else
    echo "Non è stato creato un file compresso del log"
  fi
  
  echo $'Script terminato\n'
  exit 0
}

# --------------------------------------------------------------------------
# Funzioni relative a ciascun problema selezionato
# --------------------------------------------------------------------------

# Informazioni comuni a tutti i tipi di problema
function _common {
  _data
  _lastupd
  _dmi_decode
  _comando "/bin/uname -a"
  _file "/etc/debian_version"
  _de_wm
  _file "/etc/X11/default-display-manager"
  _comando "/usr/bin/groups" "su"
  _file "/var/log/syslog"
  _comando "/bin/dmesg -l err"
  _comando "/bin/dmesg -l warn"
  _comando "/bin/lsmod"
  _comando "/usr/bin/lspci -knn"
  _comando "/usr/bin/lsusb"
  _file "/etc/apt/sources.list"
  _dir "/etc/apt/sources.list.d/"
  _comando "/sbin/fdisk -l"
  _file "/etc/fstab"
  _comando "/bin/findmnt"
  _comando "/bin/df"
  _comando "/usr/bin/apt-cache policy"
  _comando "/usr/bin/apt-cache stats"
  _comando "/usr/bin/apt-get check"
  _firmware
  _extpack
  _pack "linux-headers"
  _pack "linux-image"
  _comando "/usr/sbin/dkms status"
}

# Funzione relativa ai problemi di rete
function _rete {
  _common
  _file "/etc/network/interfaces"
  _file "/etc/hosts"
  _comando "/sbin/ifconfig"
  _comando "/sbin/ifconfig -a"
  _comando "/usr/sbin/rfkill list all"
  _comando "/bin/ping -c3 8.8.8.8" #DNS di Google 8.8.8.8
  _comando "/bin/ip addr"
  _comando "/bin/ip route list"
  _comando "/sbin/iwconfig"
  _comando "/sbin/iwlist scan"
  _comando "/sbin/route -n"
  _pack "resolvconf"
  _file "/etc/resolv.conf"
  _pack "DHCP"
  _file "/etc/dhclient.conf"
  _file "/etc/NetworkManager/NetworkManager.conf"
  _comando "/usr/bin/nmcli dev list"
  _comando "/usr/bin/nmcli device show"
  _demone "/usr/sbin/NetworkManager" "Network Manager"
  _demone "/usr/sbin/wicd" "Wicd"
}

# Funzione relativa a problemi video
function _video {
  _common
  _file "/etc/X11/xorg.conf"
  _dir "/etc/X11/xorg.conf.d/"
  _file "/var/log/Xorg.0.log"
  _pack "xserver-xorg"
  _pack "nouveau"
  _pack "nvidia"
  _pack "mesa"
  _pack "fglrx"
}

# Funzione relativa ai problemi audio. Scarica ed esegue lo script ALSA
function _audio {
  _common
  _pack "alsa"
  
  local risp alsaurl="http://www.alsa-project.org/alsa-info.sh"
  
  echo $'\nI log relativi ai problemi audio sono ricavati attraverso lo script di debug'
  echo "ALSA prelevabile all'indirizzo: ${alsaurl}"
  echo -n $'\nVerrà ora scaricato e eseguito lo script ALSA. Continuare [S/n]? '
  read risp
  case "$risp" in
    ""|[Ss])
	  # wget esiste?
	  if [ ! -f /usr/bin/wget ]; then
	    echo "Impossibile scaricare lo script ALSA. Installare il pacchetto wget."
	    return
	  fi
	  # Crea un file temporaneo in /tmp che conterrà lo script ALSA
    	  local tempfile=$(mktemp)
    	  # Scarica lo script ALSA
          _prompt "Download script ALSA"
	  wget -q -O "$tempfile" "$alsaurl"
	  # Se il download riesce...
	  if [ $? -eq 0 ]; then
	      _ok "Download script ALSA riuscito"
	      # Imposta i permessi dello script scaricato
	      chmod 777 "$tempfile"
	      nome_e_riga "Problemi audio"
	      # Esegue lo script ALSA
              _prompt "Esecuzione script ALSA"
	      su  -c "$tempfile --stdout >> $log" "$utente" && _ok || _error
	  else
	      _error "Download script ALSA fallito"
	  fi
	  
	  # Rimuove il file temporaneo
	  rm -- "$tempfile"
	  ;;
    *)
	  echo "Lo script ALSA non è stato ancora eseguito."
	  echo "Avviare manualmente lo script prelevabile a questo indirizzo:"
	  _bold "$alsaurl"
	  echo "Lo script ALSA va eseguito con i permessi di normale utente."
  esac
  
}

# Funzione relativa alla gestione dei pacchetti attraverso il sistema APT
function _apt {
  _common
  _comando "/usr/bin/dpkg --print-architecture"
  _comando "/usr/bin/dpkg --print-foreign-architectures"
  _comando "/usr/bin/apt-get update"
  _comando "/usr/bin/apt-get -s -y upgrade"
  _comando "/usr/bin/apt-get -s -y dist-upgrade"
  _comando "/usr/bin/apt-get -s -y -f install"
  _comando "/usr/bin/apt-get -s -y autoremove"
  _comando "/usr/bin/apt-config dump"
  _file "/etc/apt/apt.conf"
  _dir "/etc/apt/apt.conf.d/"
  _file "/etc/apt/preferences"
  _dir "/etc/apt/preferences.d/"
}

# Funzione relativa a problemi di mount/unmount
function _mount {
  _common
  _comando "/usr/bin/udisks --dump"
  _comando "/usr/bin/udisksctl dump"
  _pack "usbmount"
}

# Funzione relativa al funzionamento del touchpad
function _tpad {
  _common
  _pack "xserver-xorg"
  _pack "touchpad"
  _file "/etc/X11/xorg.conf"
  _dir "/etc/X11/xorg.conf.d/"
  _file "/var/log/Xorg.0.log"
  _comando "/usr/bin/synclient -l" "su"
}

# --------------------------------------------------------------------------
# Funzioni utilizzate per tipo di problema (generiche)
# --------------------------------------------------------------------------

# Funzione che invia il contenuto di un file al file di log
# La funzione va richiamata specificando il path completo del file che sarà assegnato a $1
# Il contenuto dei file viene inviato inalterato al file di log. Se si ha necessità di
# modificare questo comportamento, creare una entry nel ciclo "case"

function _file {
    nome_e_riga "$1"
    _prompt "$1"
    if [ -f "$1" ]; then
	case "$1" in
	    /etc/network/interfaces)
                      # Nasconde nel log gli ESSID e le password criptate contenute in /etc/network/interfaces
		      sed -r "s/((wpa-ssid)|(wpa-psk)).*/\1 \*script-removed\*/" "$1" &>> "$log" && _ok  || _error ;;
	    /var/log/syslog)
		      # se il file contiene la stringa "rsyslogd.*start" ...
		      if [ "$(grep -sci 'rsyslogd.*start$' "$1")" -ne 0 ]; then
			# ... estrae da syslog tutto il contenuto dall'ultima occorrenza della stringa alla fine del file
			sed -n 'H; /rsyslogd.*start$/h; ${g;p;}' "$1" >> "$log" && _ok || _error
		      else
			# se syslog non contiene quella stringa, allora si effettuerà la stessa operazione su syslog.1 ($1.1)
			# in questo caso l'intero contenuto del file syslog viene inviato al log
			cat "$1" &>> "$log" && _ok || _error
			nome_e_riga "$1".1
                        _prompt "$1".1
			sed -n 'H; /rsyslogd.*start$/h; ${g;p;}' "$1".1 >> "$log" && _ok || _error
		      fi ;;
	    *)
		      # per tutti i file non specificati sopra...
		      cat "$1" &>> "$log" && _ok || _error
	esac
    else
      echo "File \"$1\" non trovato" >> "$log" && _error
    fi
}

# Invia l'output di un comando al file di log
# La funzione va richiamata specificando il path completo del comando (con eventuali opzioni)
# che sarà assegnato a $1 . L'output dei comandi viene inviato interamente al file di log. Se
# si ha necessità di modificare gli output, creare una entry nel ciclo "case"
# Es. _comando "/usr/bin/apt-get update"
#
# Nel caso in cui il comando debba essere eseguito tramite 'su', richiamare la funzione con
# due parametri:
# $1 = il comando da eseguire attraverso 'su'
# $2 = la stringa 'su'
# Es. _comando "/usr/bin/groups" "su"

function _comando {

  local var=${1##*/} # var conterrà il comando ($1) con le opzioni ma privo del path
  local var2=${1%% *} # var2 conterrà il comando ($1) privo di eventuali opzioni ma con il path
  nome_e_riga "$var"
  _prompt "$var"
  
  if [ -f "$var2" ]; then # il comando esiste?
      if [ $# -eq 2 ]; then # Se vi sono 2 parametri, viene utilizzato "su"
	  case "$1" in
	      "/usr/bin/synclient -l")
		      # se $DISPLAY è vuota, usa :0 (default per il primo server X)
		      su -c "DISPLAY=${DISPLAY:-:0} $1" "$utente" &>> "$log" _ok || _error ;;
	      *)    
		      su -c "$1" "$utente" &>> "$log" && _ok || _error
	  esac
      else # non viene utilizzato "su"
	  case "$1" in
	      # per "iwconfig" e "iwlist scan" gli ESSID non vengono inviati al log
	      /sbin/iwconfig)
		  (iwconfig | sed -e '/ESSID:/{/off\/any/! s/ESSID:.*/ESSID:"*script-removed*"/g}' -e '/^[ ]*IE: Unknown:.*/d') &>> "$log" && _ok || _error
		  ;;
	      "/sbin/iwlist scan")
		  (iwlist scan | sed -e '/ESSID:.*/{/off\/any/! s/ESSID:.*/ESSID:"*script-removed*"/g}' -e '/^[ ]*IE: Unknown:.*/d') &>> "$log" && _ok || _error
		  ;;
              # nasconde gli ESSID visualizzati da "nmcli dev list" (solo per Wheezy)
              # L'array PIPESTATUS mostra il codice d'uscita dei comandi della pipe. PIPESTATUS[0] è il codice d'uscita di "nmcli dev list" (0=successo)
              "/usr/bin/nmcli dev list")
                  nmcli dev list 2>/dev/null | sed -r "s/(^AP[[:digit:]]*\.SSID:[[:space:]]*).*/\1\*script removed\*/" >> "$log" && [ "${PIPESTATUS[0]}" -eq 0 ] && _ok || \
                       ( _error && echo "Comando valido solo per Wheezy" >> "$log" ) ;;
              # nasconde gli ESSID visualizzati da "nmcli device show" (solo per Jessie e superiori)
              "/usr/bin/nmcli device show")
                  nmcli device show 2>/dev/null | sed -r "s/(^AP[[:digit:]]*\.SSID:[[:space:]]*).*/\1\*script removed\*/" >> "$log" && [ "${PIPESTATUS[0]}" -eq 0 ] && _ok || \
                       ( _error && echo "Comando valido solo per Jessie" >> "$log" ) ;;
	      *)
		  # per tutti gli altri comandi non specificati sopra l'output del comando è inviato inalterato al log
		  $1 &>> "$log" && _ok || _error
	  esac	  
      fi
  else
      echo "Comando \"${var2}\" non trovato" >> "$log" && _error
  fi
}

# Funzione che invia il contenuto dei file di una directory al file di log
function _dir {
  nome_e_riga "$1"
  _prompt "$1"

  # Se la directory non esiste, stampa un output sul log ed esce.
  if [ ! -d "$1" ]; then
    echo "La directory non esiste" >> "$log" && _error
    return
  fi

  # Variabili locali
  local file
  # numfile contiene il numero di file contenuti nella directory. Solo primo livello.
  local numfile=$(find "$1" -maxdepth 1 -type f | wc -l)
  # numdir contiene il numero di sottodirectory contenute nella directory. Solo primo livello.
  local numdir=$(find "$1" -maxdepth 1 -type d | wc -l)

  if [ "$numfile" -eq 0 ] && [ "$numdir" -eq 1 ]; then
    echo "La directory non contiene file o directory" >> "$log" && _error
  else
    echo "La directory contiene ${numfile} file e $(($numdir - 1)) directory" >> "$log"
    ls -al "$1" >> "$log"
    # invia al log il contenuto dei file della directory
    for file in "$1"*; do
      if [ -f "$file" ]; then
        nome_e_riga "$file"
        _prompt "$file"
        cat "$file" &>> "$log" && _ok || _error
      fi
    done

    # Funzione che invia al log il contenuto dei file presenti nelle sottodirectory
    # I due cicli "for" sono separati per permettere l'output di un file subito dopo
    # la directory a cui appartiene
    for file in "$1"*; do
      if [ -d "$file" ]; then
	_dir "$file/"
      fi
    done
  fi
}

# Funzione che elenca i pacchetti installati in base alla parola
# passata come parametro ($1)

function _pack {
  nome_e_riga "Pacchetti che contengono \"$1\""
  _prompt "$1"

  # Variabile che contiene i pacchetti trovati
  local packages=$(dpkg -l | grep -i "$1")

  if [ -z "$packages" ]; then
     echo "Nessun pacchetto installato" >> "$log" && _error
  else
     echo "$packages" >> "$log" && _ok
  fi
}

# Funzione che verifica l'esistenza e l'esecuzione di alcuni demoni
# Viene chiamata con due parametri:
# $1 - percorso dell'eseguibile
# $2 - nome da visualizzare
# Se si vuol visualizzare la versione del demone, inserire il comando adatto
# all'interno del ciclo 'case', allo stesso modo specificare al suo interno
# anche il nome dello script d'avvio per fermare, avviare, etc il demone

function _demone {

  # vers = versione del demone ; var = nome dello script d'avvio del demone
  local vers="" var=""
  nome_e_riga "$2"
  _prompt "$2"
  if [ -f "$1" ]; then
    case "$1" in
	/usr/sbin/NetworkManager)
                                  vers=$(NetworkManager --version)
                                  var="network-manager"
                                  ;;
	/usr/sbin/wicd)
                                  vers=$(wicd -h | head -2 | tail -1)
                                  var="wicd"
                                  ;;
    esac
   
    echo "$2 è installato (versione "$vers")" >> "$log" && _ok
    invoke-rc.d "$var" status &>/dev/null
    [ $? -eq 0 ] && echo "$2 è in esecuzione" >> "$log" || echo "$2 non è in esecuzione" >> "$log"
  else
    echo "$2 non è installato" >> "$log" && _error
  fi
}

# --------------------------------------------------------------------------
# Funzioni utilizzate per tipo di problema (particolari)
# --------------------------------------------------------------------------

# comando 'cat /sys/class/dmi/id/{sys_vendor,product_name,product_version,bios_version}'
function _dmi_decode {
  local var="/sys/class/dmi/id/*"
  nome_e_riga "$var"
  _prompt "$var"
  if [ -f /sys/class/dmi/id/sys_vendor ]; then
    echo "Produttore: $(cat /sys/class/dmi/id/sys_vendor)"      &>> "$log"
    echo "Prodotto:   $(cat /sys/class/dmi/id/product_name)"    &>> "$log"
    echo "Versione:   $(cat /sys/class/dmi/id/product_version)" &>> "$log"
    echo "BIOS vers.: $(cat /sys/class/dmi/id/bios_version)"    &>> "$log" && _ok || _error
  else
    echo "File /sys/class/dmi/id/sys_vendor non trovato" >> "$log" && _error
  fi
}

# esistenza di pacchetti contenenti firmware e firmware presente sulla macchina
function _firmware {
  local i var="Firmware"
  _prompt "$var"
  nome_e_riga "$var"
  dpkg -l | grep -i firmware >> "$log" && _ok
  echo >> "$log"

  # Elenca i file contenuti nelle directory specificate
  for i in "/usr/lib/firmware" "/usr/local/lib/firmware" "/lib/firmware" "/run/udev/firmware-missing"; do
    if [ -d "$i" ]; then
      echo "Contenuto di ${i}" >> "$log"
      ls -al "$i" >> "$log"
    else
      echo "${i} non trovata" >> "$log"
    fi
    echo >> "$log"
  done
}

# Stampa sullo standard output l'eseguibile associato a x-session-manager (il default)
function _x_session_manager {
  update-alternatives --query "x-session-manager" |
    awk '$1 ~ /^Value:$/ { print $2; exit 0 }'
}

# Stampa sullo standard output l'eseguibile associato a x-window-manager (il default)
function _x_window_manager {
  update-alternatives --query "x-window-manager" |
    awk '$1 ~ /^Value:$/ { print $2; exit 0 }'
}

# Stampa la lista dei pacchetti installati che soddisfano una data dipendenza
# con versione (del programma e in Debian) e archivio di provenienza
# Viene chiamata con un parametro:
# $1 - nome della dipendenza
function _soddisfa {
  echo "Installati (${1}):"
  aptitude search '?installed?provides('"$1"')' --disable-columns \
    --display-format "- %p (versione: %v; archivio: %t)"
}

# Restituisce un exit status di 0 solo se l'eseguibile con il nome scelto è in esecuzione da parte dell'utente ($utente)
# Viene chiamata con un parametro:
# $1 - comando di cui controllare l'esecuzione da parte di $utente
function _is_running {
  local list_pids_user list_pids_bin pid pid2
  list_pids_user=$(ps -U "$utente" -o pid) # lista di interi, separati da spazi, con i PID dei processi avviati da $utente
  list_pids_bin=$(pidof -- "$1")           # lista di interi, separati da spazi, con i PID dei processi del comando $1
  for pid in $list_pids_user; do
    for pid2 in $list_pids_bin; do
      if [ "$pid" = "$pid2" ]; then
        return 0  # trovato
      fi
    done
  done
  return 1        # non trovato!
}

# Funzione che "cerca" di ricavare il nome e la versione del DE/WM utilizzato
function _de_wm {
  nome_e_riga "Desktop Environment - Window Manager"
  _prompt "DE/WM"
  {
    # impostazione di default
    echo -n $'Default:\n- x-session-manager: '
    _x_session_manager
    echo -n "- x-window-manager: "
    _x_window_manager
    # installati
    _soddisfa "x-session-manager"
    #_soddisfa "x-window-manager" # non essenziale e impiega già tanto
  } >> "$log"
  # in esecuzione
  echo -n "In esecuzione: " >> "$log"
  if _is_running "ksmserver"; then kde4-config --version >> "$log" && _ok || _error                         # KDE4
  elif _is_running "gnome-shell"; then gnome-shell --version >> "$log" && _ok || _error                     # Gnome Shell
  elif _is_running "xfdesktop"; then xfce4-about -V | head -n1 | cut -d ' ' -f2- >> "$log" && _ok || _error # Xfce4
  elif _is_running "openbox"; then
    if [ "$(_x_session_manager)" != "/usr/bin/openbox-session" ]; then
      echo -n "(altro x-session-manager) + " >> "$log"                                                                      # Session manager (LXDE?) + Openbox
    fi
    openbox --version | head -n 1 >> "$log" && _ok || _error                                                # Openbox
  else
    echo "Sconosciuto" >> "$log" && _error                                                                          # NON TROVATO
  fi
}

# Funzione che elenca i pacchetti non appartenenti alla release di default utilizzata
function _extpack {

 local riga indirizzo rel linea release=""
   
 # variabile con il contenuto del file sources.list (solo righe che iniziano con deb
 # e che contengono "main" )
 local sourceslist="$(sed -e '/^deb /!d' -e '/.* main.*/!d' /etc/apt/sources.list)"
 
 # variabile che contiene l'output del comando "apt-cache policy"
 local aptcachepol="$(apt-cache policy)"

 # ciclo sulle righe della variabile "sourceslist"
 while read linea; do
   
    # variabile che contiene l'URL dell'archivio (es. http://ftp.it.debian.org/debian/)
    indirizzo="$(echo "$linea" | awk '{print $2}')"

    # sostituisce / con \/ (necessario per il successivo sed)
    indirizzo="${indirizzo//\//\\/}"

    # release della riga corrente (es. wheezy o testing o sid)
    rel="$(echo "$linea" | awk '{print $3}')"

    # controlla che sia un nome di release valido
    if [ "$rel" = "stable" ] || [ "$rel" = "testing" ] || [ "$rel" = "unstable" ] ||
       [ "$rel" = "$STABLE" ] || [ "$rel" = "$TESTING" ] || [ "$rel" = "sid" ]; then
     
       # controlla che sia un repository di Debian
       # si basa sull'output di "apt-cache policy" e su o=Debian e l=Debian
       riga="$(echo "$aptcachepol" | sed -n '/'$indirizzo'.*'$rel'\/main.*Packages$/ {N; /.*o=Debian,.*l=Debian,/p}')"
     
       # se è un archivio valido, aggiorna la variabile "release"
        if [ ! -z "$riga" ]; then
           if [ -z "$release" ]; then
              release="$rel"
           else
              release="$(printf %b "$release\n$rel")"
           fi
        fi
    fi
 done <<< "$sourceslist"

 local var="Pacchetti esterni"
 _prompt "$var"
   
 # Lo script DEVE rilevare almeno una release. Se la variabile "release" è nulla, c'è un errore nei in "sources.list"
 # oppure non è stato eseguito un aggiornamento della lista dei pacchetti (update)
 # (vedere anche il modo in cui viene ricavata la variabile "release" in alto)
 if [ -z "$release" ]; then
    nome_e_riga "${var} all'archivio \"NON RILEVATO!\""
    echo "Release non rilevata. Repository errati oppure è necessaria una modifica dello script" >> "$log" && _error
    return 1
 fi

 # Numero di release trovate
 local num=$(echo "$release" | wc -l)
   
 # Se il numero di release è diverso da 1, la funzione termina
 if [ "$num" -ne 1 ]; then
     nome_e_riga "$var"
     echo "Sono presenti ${num} release in sources.list" >> "$log" && _error
     return
 fi
   
 local pkg=""

 # Se il numero di release è uguale a 1, la variabile pkg conterrà i pacchetti *non* facenti parte della release
 case "$release" in
    "$STABLE"|stable)
                     release="stable"
                     pkg=$(aptitude -F '%p %v %t' search '~S ~i !~Astable'   --disable-columns | column -t) ;;
    "$TESTING"|testing)
                     release="testing"
                     pkg=$(aptitude -F '%p %v %t' search '~S ~i !~Atesting'  --disable-columns | column -t) ;;
    sid|unstable)  
                     release="unstable"
                     pkg=$(aptitude -F '%p %v %t' search '~S ~i !~Aunstable' --disable-columns | column -t) ;;
 esac

 # Invia al log il contenuto di pkg (se esiste)
 nome_e_riga "${var} all'archivio \"${release}\""
 if [ -z "$pkg" ]; then
     echo "Nessun pacchetto esterno installato" >> "$log" && _error
 else
     echo "$pkg" >> "$log" && _ok
 fi
}


# --------------------------------------------------------------------------
# Main
# --------------------------------------------------------------------------

clear

_intro
_avvertenze
_check
_scelta
_hide
_upload
_compress
_exit

Changelog

1.0.50
Rivista la funzione _extpack (repository Debian
in base al comando "apt-cache policy"
S3v 22:37, 22 dic 2014 (CET)
1.0.49
Aggiunti trap INT e "dpkg-foreign-architectures"
Spostato "dkms status" nei comandi generali
S3v 21:19, 20 dic 2014 (CET)
1.0.48
Corretta la ricerca per i pacchetti esterni
Aggiunto _pack "linux-image"
S3v 20:16, 19 nov 2014 (CET)
1.0.47
Inseriti "nmcli dev list" (per Wheezy) e "nmcli device show" (per Jessie e superiori)
Inserito "udisksctl dump"
S3v 15:55, 5 nov 2014 (CET)

(Prosegue nella pagina di discussione).




Guida scritta da: S3v 23:38, 13 apr 2013 (CEST) Swirl-auth20.png Debianized 20%
Estesa da:
Verificata da:

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