Capitolo 16. Comandi di sistema e d'amministrazione

Gli script di avvio (startup) e di arresto (shutdown) presenti in /etc/rc.d illustrano gli usi (e l'utilità) di molti dei comandi che seguono. Questi, di solito, vengono invocati dall'utente root ed utilizzati per la gestione del sistema e per le riparazioni d'emergenza del filesystem. Vanno usati con attenzione poiché alcuni di questi comandi, se utilizzati in modo maldestro, possono danneggiare il sistema stesso.

Utenti e gruppi

users

Visualizza tutti gli utenti presenti sul sistema. Equivale approssimativamente a who -q.

groups

Elenca l'utente corrente ed i gruppi a cui appartiene. Corrisponde alla variabile interna $GROUPS, ma, anziché indicare i gruppi con i numeri corrispondenti, li elenca con i loro nomi.

bash$ groups
bozita cdrom cdwriter audio xgrp

bash$ echo $GROUPS
501
chown, chgrp

Il comando chown modifica la proprietà di uno o più file. Questo comando rappresenta un metodo utile che root può usare per spostare la proprietà di un file da un utente all'altro. Un utente ordinario non può modificare la proprietà dei file, neanche dei propri. [1]

root# chown bozo *.txt

	      

Il comando chgrp modifica il gruppo proprietario di uno o più file. Occorre essere il proprietario del/dei file e membro del gruppo di destinazione (o root) per poter effettuare questa operazione.

chgrp --recursive dunderheads *.data
#  Il gruppo "dunderheads" adesso è proprietario di tutti i file"*.data"
#+ presenti nella directory $PWD (questo è il significato di "recursive").

useradd, userdel

Il comando d'amministrazione useradd aggiunge l'account di un utente al sistema e, se specificato, crea la sua directory home. Il corrispondente comando userdel cancella un utente dal sistema [2] ed i file ad esso associati.

Nota

Il comando adduser è il sinonimo di useradd nonché, di solito, un link simbolico ad esso.

usermod

Modifica l'account di un utente. La variazione può riguardare la password, il gruppo d'appartenenza, la data di scadenza ed altri attributi dell'account di un determinato utente. Con questo comando è possibile anche bloccare la password di un utente, con il risultato di disabilitare l'account dello stesso.

groupmod

Modifica gli attributi di un dato gruppo. Usando questo comando si può cambiare il nome del gruppo e/o il suo numero ID.

id

Il comando id elenca i reali ID utente e di gruppo dell'utente associato al processo corrente. È il corrispettivo delle variabili interne Bash $UID, $EUID e $GROUPS.

bash$ id
uid=501(bozo) gid=501(bozo) groups=501(bozo),22(cdrom),80(cdwriter),81(audio)

bash$ echo $UID
501

Nota

id mostra gli ID effettivi solo quando questi sono diversi da quelli reali.

Vedi anche Esempio 9-5.

who

Visualizza tutti gli utenti connessi al sistema.

bash$ who
bozo  tty1     Apr 27 17:45
bozo  pts/0    Apr 27 17:46
bozo  pts/1    Apr 27 17:47
bozo  pts/2    Apr 27 17:49
	      

L'opzione -m fornisce informazioni solo sull'utente corrente. Passare a who due argomenti, come nel caso di who am i o who The Man equivale a who -m.

bash$ who -m
localhost.localdomain!bozo  pts/2    Apr 27 17:49
	      

whoami è simile a who -m, ma elenca semplicemente il nome dell'utente.

bash$ whoami
bozo
	      

w

Visualizza tutti gli utenti connessi ed i processi di loro appartenenza. È la versione estesa di who. L'output di w può essere collegato con una pipe a grep per la ricerca di un utente e/o processo specifico.

bash$ w | grep startx
bozo  tty1     -                 4:22pm  6:41   4.47s  0.45s  startx
logname

Visualizza il nome di login dell'utente corrente (così come si trova in /var/run/utmp). Equivale, quasi, al precedente whoami.

bash$ logname
bozo

bash$ whoami
bozo

Tuttavia . . .

bash$ su
Password: ......

bash# whoami
root
bash# logname
bozo

Nota

Mentre logname visualizza il nome dell'utente connesso, whoami fornisce il nome dell'utente collegato al processo corrente. Come si è appena visto, talvolta questi non coincidono.

su

Esegue un programma o uno script come utente diverso (substitute user). su rjones esegue una shell come utente rjones. Il semplice su fa riferimento, in modo predefinito, all'utente root. Vedi Esempio A-15.

sudo

Esegue un comando come root (o altro utente). Può essere utilizzato in uno script, consentendone così l'esecuzione ad un utente ordinario.

#!/bin/bash

# Alcuni comandi.
sudo cp /root/secretfile /home/bozo/secret
# Ulteriori comandi.

Il file /etc/sudoers contiene i nomi degli utenti autorizzati ad invocare sudo.

passwd

Imposta, modifica o gestisce la password dell'utente.

passwd può essere utilizzato in uno script, ma questo, possibilmente, non dovrebbe essere fatto.

Esempio 16-1. Impostare una nuova password

#!/bin/bash
#  setnew-password.sh: A solo scopo dimostrativo.
#                      Non è una buona idea eseguire veramente questo script.
#  Deve essere eseguito da root.

UID_ROOT=0          # Root ha $UID 0.
E_UTENTE_ERRATO=65  # Non root?

E_UTENTE_INESISTENTE=70
SUCCESSO=0


if [ "$UID" -ne "$UID_ROOT" ]
then
  echo; echo "Solo root può eseguire lo script."; echo
  exit $E_UTENTE_ERRATO
else
  echo
  echo "Root, dovresti saper far di meglio che non eseguire questo script."
  echo "Anche gli utenti root hanno le loro giornate storte... "
  echo
fi  


nomeutente=bozo
NUOVAPASSWORD=violazione_sicurezza

# Controlla se l'utente bozo esiste.
grep -q "$nomeutente" /etc/passwd
if [ $? -ne $SUCCESSO ]
then
  echo "L'utente $nomeutente non esiste."
  echo "Nessuna password modificata."
  exit $E_UTENTE_INESISTENTE
fi

echo "$NUOVAPASSWORD" | passwd --stdin "$nomeutente"
#  L'opzione '--stdin' di 'passwd' consente di
#+ ottenere la nuova password dallo stdin (o da una pipe).

echo; echo "E' stata cambiata la password dell'utente $nomeutente!"

# E' pericoloso usare il comando 'passwd' in uno script.

exit 0

Le opzioni -l, -u e -d del comando passwd consentono di bloccare, sbloccare e cancellare la password di un utente. Solamente root può usare queste opzioni.

ac

Visualizza la durata della connessione di un utente al sistema, letta da /var/log/wtmp. Questa è una delle utility di contabilità GNU.

bash$ ac
total       68.08
last

Elenca gli ultimi utenti connessi, letti da /var/log/wtmp. Questo comando consente anche la visualizzazione dei login effettuati da remoto.

Ad esempio, per visualizzare gli ultimi riavvii del sistema:

bash$ last reboot
 reboot   system boot  2.6.9-1.667      Fri Feb  4 18:18          (00:02)    
 reboot   system boot  2.6.9-1.667      Fri Feb  4 15:20          (01:27)    
 reboot   system boot  2.6.9-1.667      Fri Feb  4 12:56          (00:49)    
 reboot   system boot  2.6.9-1.667      Thu Feb  3 21:08          (02:17)    
 . . .

 wtmp begins Tue Feb  1 12:50:09 2005
newgrp

Modifica l'ID di gruppo dell'utente senza doversi disconnettere. Consente l'accesso ai file di un nuovo gruppo. Poiché gli utenti possono appartenere contemporaneamente a più gruppi, questo comando viene poco utilizzato.

Terminali

tty

Visualizza il nome del terminale dell'utente corrente. È da notare che ciascuna differente finestra di xterm viene considerata come un diverso terminale.

bash$ tty
/dev/pts/1
stty

Mostra e/o modifica le impostazioni del terminale. Questo complesso comando, usato in uno script, riesce a controllare il comportamento del terminale e le modalità di visualizzazione degli output. Si veda la sua pagina info e la si studi attentamente.

Esempio 16-2. Abilitare un carattere di cancellazione

#!/bin/bash
# erase.sh: Uso di "stty" per impostare un carattere di cancellazione nella 
#+          lettura dell'input.

echo -n "Come ti chiami? "
read nome                      #  Provate ad usare il tasto di ritorno
                               #+ (backspace) per cancellare i caratteri
                               #+ digitati. Problemi?.
echo "Ti chiami $nome."

stty erase '#'                 #  Imposta il carattere "hash" (#) come 
                               #+ carattere di cancellazione.
echo -n "Come ti chiami? "
read nome                      #  Usate # per cancellare l'ultimo carattere
                               #+ digitato.
echo "Ti chiami $nome."

# Questa impostazione permane anche dopo l'uscita dallo script.
#  Esercizio: come si potrebbe reimpostare il carattere di cancellazione
#+ al valore preimpostato?

exit 0

Esempio 16-3. Password segreta: disabilitare la visualizzazione a terminale

#!/bin/bash
# secret-pw.sh: password segreta

echo
echo -n "Immetti la password "
read passwd
echo "La password è $passwd"
echo -n "Se qualcuno stesse sbirciando da dietro le vostre spalle,"
echo "la password sarebbe compromessa."

echo && echo  # Due righe vuote con una "lista and".

stty -echo    # Disabilita la visualizzazione sullo schermo.

echo -n "Reimmetti la password "
read passwd
echo
echo "La password è $passwd"
echo

stty echo     # Ripristina la visualizzazione sullo schermo.

exit 0

#  Effettuate un 'info stty' per maggiori informazioni su questo utile,
#+ ma complesso, comando.

Un uso creativo di stty è quello di rilevare i tasti premuti dall'utente (senza dover premere successivamente INVIO).

Esempio 16-4. Rilevamento dei tasti premuti

#!/bin/bash
# keypress.sh: Rileva i tasti premuti dall'utente ("tasti bollenti").

echo

precedenti_impostazioni_tty=$(stty -g)  # Salva le precedenti impostazioni
                                        # (perché?).
stty -icanon
tasti=$(head -c1)             #  Oppure $(dd bs=1 count=1 2> /dev/null)
                              #+ su sistemi non-GNU

echo
echo "Hai premuto i tasti \""$tasti"\"."
echo

stty "$precedenti_impostazioni_tty"     # Ripristina le precedenti impostazioni.

# Grazie, Stephane Chazelas.

exit 0

Vedi anche Esempio 9-3.

setterm

Imposta alcuni attributi del terminale. Questo comando scrive una stringa nello stdout del proprio terminale con la quale modifica il comportamento del terminale stesso.

bash$ setterm -cursor off
bash$
	      

setterm può essere usato in uno script per modificare le modalità: di visualizzazione di un testo allo stdout, anche se esistono certamente strumenti migliori per questo scopo.

setterm -bold on
echo ciao in grassetto

setterm -bold off
echo ciao normale

tset

Mostra o inizializza le impostazioni del terminale. È una versione meno potente di stty.

bash$ tset -r
Terminal type is xterm-xfree86.
Kill is control-U (^U).
Interrupt is control-C (^C).
	      

setserial

Imposta o visualizza i parametri di una porta seriale. Questo comando deve essere eseguito dall'utente root e si trova, di solito, in uno script di avvio del sistema.

# Dallo script /etc/pcmcia/serial:

IRQ=`setserial /dev/$DEVICE | sed -e 's/.*IRQ: //'`
setserial /dev/$DEVICE irq 0 ; setserial /dev/$DEVICE irq $IRQ

getty, agetty

Il processo di inizializzazione di un terminale utilizza getty o agetty per l'impostazione del login di un utente. Questi comandi non vengono usati negli script di shell. Il loro corrispondente per lo scripting è stty.

mesg

Abilita o disabilita l'accesso in scrittura al terminale dell'utente corrente. Disabilitando l'accesso si impedisce ad un altro utente della rete di scrivere su quel terminale.

Suggerimento

Può risultare piuttosto fastidioso veder comparire improvvisamente un messaggio d'ordinazione di una pizza nel bel mezzo di un file di testo su cui si sta lavorando. Su una rete multi-utente, potrebbe essere desiderabile disabilitare l'accesso in scrittura al terminale quando si ha bisogno di evitare qualsiasi interruzione.

wall

È l'acronimo di " write all", vale a dire, invia un messaggio ad ogni terminale di ciascun utente collegato alla rete. Si tratta, innanzi tutto, di uno strumento dell'amministratore di sistema, utile, per esempio, quando occorre avvertire tutti gli utenti che la sessione dovrà essere arrestata a causa di un determinato problema (vedi Esempio 18-1).

bash$ wall Tra 5 minuti Il sistema verrà sospeso per manutenzione!
Broadcast message from ecobel (pts/1) Sun Jul  8 13:53:27 2001...

Tra 5 minuti il sistema verrà sospeso per manutenzione!
	      

Nota

Se l'accesso in scrittura di un particolare terminale è stato disabilitato con mesg, allora wall non potrà inviare nessun messaggio a quel terminale.

Informazioni e statistiche

uname

Visualizza allo stdout le specifiche di sistema (SO, versione del kernel, ecc). Invocato con l'opzione -a, fornisce le informazioni in forma dettagliata (vedi Esempio 15-5). L'opzione -s mostra solo il tipo di Sistema Operativo.

bash$ uname
Linux

bash$ uname -s
Linux

bash$ uname -a
Linux iron.bozo 2.6.15-1.2054_FC5 #1 Tue Mar 14 15:48:33 EST 2006 i686 i686 i386 GNU/Linux
arch

Mostra l'architettura del sistema. Equivale a uname -m. Vedi Esempio 10-26.

bash$ arch
i686

bash$ uname -m
i686
lastcomm

Fornisce informazioni sui comandi precedentemente eseguiti, così come sono registrati nel file /var/account/pacct. Come opzioni si possono specificare il nome del comando e dell'utente. È una delle utility di contabilità GNU.

lastlog

Elenca l'ora dell'ultimo login di tutti gli utenti del sistema. Fa riferimento al file /var/log/lastlog.

bash$ lastlog
root          tty1                      Fri Dec  7 18:43:21 -0700 2001
bin                                     **Never logged in**
daemon                                  **Never logged in**
...
bozo          tty1                      Sat Dec  8 21:14:29 -0700 2001



bash$ lastlog | grep root
root          tty1                      Fri Dec  7 18:43:21 -0700 2001
	      

Attenzione

Il comando fallisce se l'utente che l'ha invocato non possiede i permessi di lettura sul file /var/log/lastlog.

lsof

Elenca i file aperti. Questo comando visualizza una tabella dettagliata di tutti i file aperti in quel momento e fornisce informazioni sui loro proprietari, sulle dimensioni, sui processi ad essi associati ed altro ancora. Naturalmente, lsof può essere collegato tramite una pipe a grep e/o awk per verificare ed analizzare il risultato.

bash$ lsof
COMMAND    PID    USER   FD   TYPE     DEVICE    SIZE  NODE NAME
init         1    root  mem    REG        3,5   30748    30303 /sbin/init
init         1    root  mem    REG        3,5   73120     8069 /lib/ld-2.1.3.so
init         1    root  mem    REG        3,5  931668     8075 /lib/libc-2.1.3.so
cardmgr    213    root  mem    REG        3,5   36956    30357 /sbin/cardmgr
...
	      

Il comando lsof è un utile, anche se complesso, strumento d'amministrazione. Se non si è in grado di smontare un filesystem e si riceve il messaggio d'errore che è ancora in uso, allora l'esecuzione di lsof aiuta a determinare quali file sono ancora aperti in quel filesystem. L'opzione -i elenca i socket di rete aperti, aiutando così a tracciare i tentativi di intrusione o di hacking.

bash$ lsof -an -i tcp
COMMAND  PID USER  FD  TYPE DEVICE SIZE NODE NAME
  firefox 2330 bozo  32u IPv4   9956       TCP 66.0.118.137:57596->67.112.7.104:http ...
 firefox 2330 bozo  38u IPv4  10535       TCP 66.0.118.137:57708->216.79.48.24:http ...
	     

strace

Strumento diagnostico e di debugging per il tracciamento dei segnali e delle chiamate di sistema (System trace). Questo comando e ltrace, vedi oltre, sono utili per diagnosticare il motivo della mancata esecuzione di un dato programma o pacchetto. . . forse a seguito di librerie mancanti o altre cause correlate.

bash$ strace df
 execve("/bin/df", ["df"], [/* 45 vars */]) = 0
 uname({sys="Linux", node="bozo.localdomain", ...}) = 0
 brk(0)                                  = 0x804f5e4
 
 ...
	    

È l'equivalente Linux del comando truss di Solaris.

ltrace

Strumento di diagnosi e debugging che traccia le chiamate di libreria (Library trace) invocate da un dato comando.

bash$ ltrace df
__libc_start_main(0x804a910, 1, 0xbfb589a4, 0x804fb70, 0x804fb68 <unfinished ...>:
 setlocale(6, "")                                 = "en_US.UTF-8"
bindtextdomain("coreutils", "/usr/share/locale") = "/usr/share/locale"
textdomain("coreutils")                          = "coreutils"
__cxa_atexit(0x804b650, 0, 0, 0x8052bf0, 0xbfb58908) = 0
getenv("DF_BLOCK_SIZE")                          = NULL
							
...
	    

nmap

Network mapper - mappatore di rete e analizzatore di porta. Questo comando analizza un server per localizzare le porte aperte ed i servizi ad esse associati. Può anche riportare informazioni sui filtri di pacchetto e sui firewall. È un importante strumento per la sicurezza, per proteggere una rete contro tentativi di hacking.

#!/bin/bash

SERVER=$HOST                            # localhost.localdomain (127.0.0.1).
NUMERO_PORTA=25                         # porta SMTP.

nmap $SERVER | grep -w "$NUMERO_PORTA"  # Questa specifica porta è aperta?
#              grep -w verifica solamente la parola esatta,
#+             così, per esempio, non verrà verificata la porta 1025.

exit 0

# 25/tcp     open        smtp

nc

L'utility nc (netcat) è uno strumento completo per la connessione e l'ascolto sulle porte TCP e UDP. Utile per la diagnostica e le prove, nonché per client e server HTTP basati su semplici script di cui ne è la componente principale.

bash$ nc localhost.localdomain 25
220 localhost.localdomain ESMTP Sendmail 8.13.1/8.13.1; Thu, 31 Mar 2005 15:41:35 -0700

Esempio 16-5. Verificare se su un server remoto è in esecuzione identd

#! /bin/sh
## Stessa funzionalità di ident-scan di DaveG
#+ usando, però, netcat. Oooh, come sarà inc***to.
## Argomenti: porta di riferimento [porta porta porta ...]
## Blocca stdout _e_ stderr.
##
##  Vantaggi: esecuzione più lenta di ident-scan, con meno possibilità
##+ che l'inetd remoto si allarmi, e verifica i pochi demoni conosciuti in
##+ esecuzione solo sulle porte specificate.
##  Svantaggi: le porte devono essere indicate solo con il loro nummero, output 
##+ striminzito e non funziona per servizi remoti provenienti da porte con
##+ numerazione elevata.
# Autore dello script: Hobbit <hobbit@avian.org>
# Usato in Guida ASB con il suo consenso.

# ------------------------------------------------------
E_ERR_ARG=65       # Sono necessari almeno due argomenti.
DUE_PAUSE=2        # Durata dell'interruzione.
TRE_PAUSE=3
IDPORTA=113        # Porta di autenticazione "tap ident".
CAUS1=999
CAUS2=31337
TIMEOUT0=9
TIMEOUT1=8
TIMEOUT2=4
# ------------------------------------------------------

case "${2}" in
  "" ) echo "Specificate l'HOST e almeno una PORTA." ; exit $E_ERR_ARG ;;
esac

# Effettua un ping per vedere se "stanno" eseguendo identd.
nc -z -w $TIMEOUT0 "$1" $IDPORTA ||\ 
{ echo "Oops, $1 non ha in esecuzione identd." ; exit 0 ; }
#  -z effettua una scansione dei demoni in ascolto.
#     -w $TIMEOUT = Durata del tentativo di connessione.

# Genera un numero casuale per la porta di partenza.
PC=`expr $$ % $CAUS1 + $CAUS2`

BERS="$1"
shift

while test "$1" ; do
  nc -v -w $TIMEOUT1 -p ${PC} "$BERS" ${1} < /dev/null > /dev/null &
  PROC=$!
  sleep $TRE_PAUSE
  echo "${1},${PC}" | nc -w $TIMEOUT2 -r "$BERS" $IDPORTA 2>&1
  sleep $DUE_PAUSE

# Assomiglia a uno scrip per lamer o cos'altro . . . ?
# Commento dell'autore de Guida ASB: "Non è poi così male,
#+                                    a dire il vero, anzi, è piuttosto
#+                                    intelligente."

  kill -HUP $PROC
  PC=`expr ${PC} + 1`
  shift
done

exit $?

#  Note:
#  ----

#  Provate ad eseguire lo script dopo aver commentato la riga 33
#+ fornedo come argomenti "localhost.localdomain 25".

#  Per ultedriori script d'esempio di Hobbit su 'nc',
#+ date uno sguardo alla documentazione nella directory:
#+ /usr/share/doc/nc-X.XX/scripts.

Naturalmente, è presente nel ben noto script di una sola riga del Dr. Andrew Tridgell in BitKeeper Affair:

echo clone | nc thunk.org 5000 > e2fsprogs.dat

free

Mostra, in forma tabellare, l'utilizzo della memoria e della cache. Il suo output si presta molto bene alle verifiche per mezzo di grep, awk o Perl. Il comando procinfo visualizza tutte quelle informazioni che non sono fornite da free, e molto altro.

bash$ free
                total       used       free     shared buffers     cached
   Mem:         30504      28624       1880      15820    1608      16376
   -/+ buffers/cache:      10640      19864
   Swap:        68540       3128      65412

Per visualizzare la memoria RAM inutilizzata:

bash$ free | grep Mem | awk '{ print $4 }'
1880
procinfo

Ricava ed elenca informazioni e statistiche dallo pseudo-filesystem /proc. Fornisce un elenco molto ampio e dettagliato.

bash$ procinfo | grep Bootup
Bootup: Wed Mar 21 15:15:50 2001    Load average: 0.04 0.21 0.34 3/47 6829
lsdev

Elenca i dispositivi, vale a dire, l'hardware installato.

bash$ lsdev
Device            DMA   IRQ  I/O Ports
 ------------------------------------------------
cascade             4     2 
dma                          0080-008f
dma1                         0000-001f
dma2                         00c0-00df
fpu                          00f0-00ff
ide0                     14  01f0-01f7 03f6-03f6
...
	      

du

Mostra, in modo ricorsivo, l'utilizzo del (disco) file. Se non diversamente specificato, fa riferimento alla directory di lavoro corrente.

 bash$ du -ach
 1.0k    ./wi.sh
 1.0k    ./tst.sh
 1.0k    ./random.file
 6.0k    .
 6.0k    total
df

Mostra l'utilizzo del filesystem in forma tabellare.

bash$ df
Filesystem           1k-blocks      Used Available Use% Mounted on
/dev/hda5               273262     92607    166547  36% /
/dev/hda8               222525    123951     87085  59% /home
/dev/hda7              1408796   1075744    261488  80% /usr
dmesg

Elenca allo stdout tutti i messaggi generati durante la fase di boot del sistema. Utile per il "debugging" e per verificare quali driver di dispositivo sono installati e quali interrupt vengono utilizzati. L'output di dmesg può, naturalmente, essere verificato con grep, sed o awk dall'interno di uno script.

bash$ dmesg | grep hda
 Kernel command line: ro root=/dev/hda2
 hda: IBM-DLGA-23080, ATA DISK drive
 hda: 6015744 sectors (3080 MB) w/96KiB Cache, CHS=746/128/63
 hda: hda1 hda2 hda3 < hda5 hda6 hda7 > hda4
	      

stat

Fornisce ampie e dettagliate statistiche su un dato file (anche su una directory o su un file di dispositivo) o una serie di file.

bash$ stat test.cru
  File: "test.cru"
  Size: 49970        Allocated Blocks: 100          Filetype: Regular File
  Mode: (0664/-rw-rw-r--)         Uid: (  501/ bozo)  Gid: (  501/ bozo)
Device:  3,8   Inode: 18185     Links: 1
Access: Sat Jun  2 16:40:24 2001
Modify: Sat Jun  2 16:40:24 2001
Change: Sat Jun  2 16:40:24 2001
	      

Se il file di riferimento non esiste, stat restituisce un messaggio d'errore.

bash$ stat file_inesistente
file_inesistente: No such file or directory
	      

È possibile utilizzare stat in uno script per ricavare informazioni sui file (e filesystem) per usarle per impostare delle variabili.

#!/bin/bash
# fileinfo2.sh
			    
# Su suggerimento di Joël Bourquard e . . .
# http://www.linuxquestions.org/questions/showthread.php?t=410766
			    
			    
NOMEFILE=testfile.txt
nome_file=$(stat -c%n "$NOMEFILE")   # Naturalmente uguale a "$NOMEFILE".
proprietario=$(stat -c%U "$NOMEFILE")
dimensione=$(stat -c%s "$NOMEFILE")
#  Sicuramente più facile di "ls -l $NOMEFILE"
#+ filtrato successivamente con sed.
inode=$(stat -c%i "$NOMEFILE")
tipo=$(stat -c%F "$NOMEFILE")
diritti_accesso=$(stat -c%A "$NOMEFILE")
			    
echo "Nome del file:                 $nome_file"
echo "Proprietario del file:         $proprietario"
 echo "Dimensione del file:          $dimensione"
echo "Inode del file:                $inode"
echo "Tipo di file:                  $tipo"
echo "Diritti di accesso al file:    $diritti_accesso"
			    
exit 0
			    
sh fileinfo2.sh
			    
Nome del file:              testfile.txt
Proprietario del file:      bozo
Dimensione del file:        418
Inode del file:             1730378
Tipo di file:               regular file
Diritti di accesso al file: -rw-rw-r--

vmstat

Visualizza statistiche riguardanti la memoria virtuale.

bash$ vmstat
    procs                      memory    swap          io system         cpu
 r  b  w   swpd   free   buff  cache  si  so    bi    bo   in    cs  us  sy id
 0  0  0      0  11040   2636  38952   0   0    33     7  271    88   8   3 89
	    

netstat

Mostra informazioni e statistiche sulla rete corrente, come le tabelle di routing e le connessioni attive. Questa utility accede alle informazioni presenti in /proc/net (Capitolo 27). Vedi Esempio 27-3.

netstat -r equivale a route.

bash$ netstat
 Active Internet connections (w/o servers)
 Proto Recv-Q Send-Q Local Address           Foreign Address         State
 Active UNIX domain sockets (w/o servers)
 Proto RefCnt Flags       Type       State         I-Node Path
 unix  11     [ ]         DGRAM                    906    /dev/log
 unix  3      [ ]         STREAM     CONNECTED     4514   /tmp/.X11-unix/X0
 unix  3      [ ]         STREAM     CONNECTED     4513
 . . .

Nota

netstat -lptu mostra i socket in ascolto sulle porte ed i processi ad essi associati. Risulta utile per determinare se un computer è stato compromesso.

uptime

Mostra da quanto tempo il sistema è attivo, con le relative statistiche.

bash$ uptime
10:28pm  up  1:57,  3 users,  load average: 0.17, 0.34, 0.27

Nota

Un valore di load average di 1 o minore indica che il sistema gestisce i processi immediatamente. Un load average maggiore di 1 significa che i processi vengono accodati. Quando load average oltrepassa il 3 vuol dire che le prestazioni del sistema sono degradate in maniera significativa.

hostname

Visualizza il nome host del sistema. Questo comando imposta il nome dell'host in uno script di avvio in /etc/rc.d (/etc/rc.d/rc.sysinit o simile). Equivale a uname -n e corrisponde alla variabile interna $HOSTNAME.

bash$ hostname
localhost.localdomain

bash$ echo $HOSTNAME
localhost.localdomain

Simili al comando hostname sono domainname, dnsdomainname, nisdomainname e ypdomainname. Questi possono essere usati per visualizzare o impostare il DNS di sistema o il nome di dominio NIS/YP. Anche diverse opzioni di hostname svolgono queste funzioni.

hostid

Visualizza un identificatore numerico esadecimale a 32 bit dell'host della macchina.

bash$ hostid
7f0100

Nota

Si presume che questo comando possa fornire un numero di serie "unico" per un particolare sistema. Certe procedure per la registrazione di prodotto utilizzano questo numero per identificare una specifica licenza d'uso. Sfortunatamente, hostid restituisce solo l'indirizzo di rete della macchina in forma esadecimale con la trasposizione di una coppia di byte.

L'indirizzo di rete di una tipica macchina Linux, non appartenente ad una rete, si trova in /etc/hosts.

bash$ cat /etc/hosts
127.0.0.1               localhost.localdomain localhost

Si dà il caso che, con la trasposizione dei byte di 127.0.0.1, si ottiene 0.127.1.0, che trasformato in esadecimale corrisponde a 007f0100, l'esatto equivalente di quanto è stato restituito da hostid, come visto in precedenza. Solo che esistono alcuni milioni di altre macchine Linux con questo stesso hostid.

sar

L'esecuzione di sar (System Activity Report) fornisce un dettagliatissimo resoconto delle statistiche di sistema. Santa Cruz Operation (la "vecchia" SCO) ha rilasciato sar sotto licenza Open Source nel giugno 1999.

Questo comando non fa parte delle distribuzioni di base di Linux, ma è contenuto nel pacchetto sysstat utilities, scritto da Sebastien Godard.

bash$ sar
Linux 2.4.9 (brooks.seringas.fr)       09/26/03

10:30:00          CPU     %user     %nice   %system   %iowait     %idle
10:40:00          all      2.21     10.90     65.48      0.00     21.41
10:50:00          all      3.36      0.00     72.36      0.00     24.28
11:00:00          all      1.12      0.00     80.77      0.00     18.11
Average:          all      2.23      3.63     72.87      0.00     21.27

14:32:30          LINUX RESTART

15:00:00          CPU     %user     %nice   %system   %iowait     %idle
15:10:00          all      8.59      2.40     17.47      0.00     71.54
15:20:00          all      4.07      1.00     11.95      0.00     82.98
15:30:00          all      0.79      2.94      7.56      0.00     88.71
Average:          all      6.33      1.70     14.71      0.00     77.26
           
readelf

Mostra informazioni e statistiche su un file elf specificato. Fa parte del pacchetto binutils.

bash$ readelf -h /bin/bash
ELF Header:
   Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
   Class:                             ELF32
   Data:                              2's complement, little endian
   Version:                           1 (current)
   OS/ABI:                            UNIX - System V
   ABI Version:                       0
   Type:                              EXEC (Executable file)
   . . .
size

Il comando size [/percorso/del/binario] fornisce le dimensioni dei segmenti di un binario eseguibile o di un file archivio. È usato soprattutto dai programmatori.

bash$ size /bin/bash
   text    data     bss     dec     hex filename
 495971   22496   17392  535859   82d33 /bin/bash
	      

Log di sistema

logger

Accoda messaggi generati dall'utente ai log di sistema (/var/log/messages). Non è necessario essere root per invocare logger.

logger Riscontrata un'instabilità nella connessione di rete alle 23:10, 21/05.
# Ora eseguite 'tail /var/log/messages'.

Inserendo il comando logger in uno script è possibile scrivere informazioni di debugging in /var/log/messages.

logger -t $0 -i Logging alla riga "$LINENO".
# L'opzione "-t" specifica l'identificativo della registrazione di logger
# L'opzione "-i" registra l'ID di processo.

# tail /var/log/message
# ...
# Jul  7 20:48:58 localhost ./test.sh[1712]: Logging alla riga 3.

logrotate

Questa utility gestisce i file di log di sistema, effettuandone la rotazione, la compressione, la cancellazione e/o l'invio per e-mail, secondo le necessità. Questo evita che /var/log si riempia all'inverosimile di vecchi file di log. Di solito cron esegue logrotate a cadenza giornaliera.

Aggiungendo una voce appropriata in /etc/logrotate.conf è possibile gestire i file di log personali allo stesso modo di quelli di sistema.

Nota

Stefano Falsetto ha creato rottlog, che egli considera una versione migliorata di logrotate.

Controllo dei job

ps

Statistiche di processo (Process Statistics): elenca i processi attualmente in esecuzione per proprietario e PID (ID di processo). Viene solitamente invocato con le opzioni ax o aux e può essere collegato tramite una pipe a grep o sed per la ricerca di un processo specifico (vedi Esempio 14-12 e Esempio 27-2).

bash$  ps ax | grep sendmail
295 ?	   S	  0:00 sendmail: accepting connections on port 25

Per visualizzare graficamente i processi di sistema in forma di struttura ad "albero": ps afjx oppure ps ax --forest.

pgrep, pkill

Combinazione del comando ps con grep e kill.

bash$ ps a | grep mingetty
 2212 tty2     Ss+    0:00 /sbin/mingetty tty2
 2213 tty3     Ss+    0:00 /sbin/mingetty tty3
 2214 tty4     Ss+    0:00 /sbin/mingetty tty4
 2215 tty5     Ss+    0:00 /sbin/mingetty tty5
 2216 tty6     Ss+    0:00 /sbin/mingetty tty6
 4849 pts/2    S+     0:00 grep mingetty


bash$ pgrep mingetty
 2212 mingetty
 2213 mingetty
 2214 mingetty
 2215 mingetty
 2216 mingetty
	      

Si confronti l'azione di pkill con killall.

pstree

Elenca i processi attualmente in esecuzione in forma di struttura ad "albero" . L'opzione -p mostra i PID e i nomi dei processi.

top

Visualizza, in aggiornamento continuo, i processi maggiormente intensivi in termini di cpu. L'opzione -b esegue la visualizzazione in modalità testo, di modo che l'output possa essere verificato o vi si possa accedere da uno script.

bash$ top -b
  8:30pm  up 3 min,  3 users,  load average: 0.49, 0.32, 0.13
 45 processes: 44 sleeping, 1 running, 0 zombie, 0 stopped
 CPU states: 13.6% user,  7.3% system,  0.0% nice, 78.9% idle
 Mem:    78396K av,   65468K used,   12928K free,       0K shrd,    2352K buff
 Swap:  157208K av,       0K used,  157208K free                   37244K cached

 PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME COMMAND
 848 bozo      17   0   996  996   800 R     5.6  1.2   0:00 top
   1 root       8   0   512  512   444 S     0.0  0.6   0:04 init
   2 root       9   0     0    0     0 SW    0.0  0.0   0:00 keventd
   ...  
	      

nice

Esegue un job sullo sfondo (background) con priorità modificata. Le priorità vanno da 19 (la più bassa) a -20 (la più alta). Solo root può impostare le priorità negative (quelle più alte). Comandi correlati sono renice e snice, che modificano la priorità di un processo, o processi, in esecuzione, e skill, che invia il segnale kill al/ai processo/i.

nohup

Mantiene un comando in esecuzione anche dopo la disconnessione dell'utente. Il comando viene eseguito come un processo in primo piano (foreground) a meno che non sia seguito da &. Se si usa nohup in uno script, si prenda in considerazione di accoppiarlo a wait per evitare di creare un processo orfano o zombie.

pidof

Identifica l'ID di processo (PID) di un job in esecuzione. Poiché i comandi di controllo dei job, come kill e renice, agiscono sul PID di un processo (non sul suo nome), è necessario identificare quel determinato PID. Il comando pidof è approssimativamente simile alla variabile interna $PPID.

bash$ pidof xclock
880
	      

Esempio 16-6. pidof aiuta ad terminare un processo

#!/bin/bash
# kill-process.sh

NESSUNPROCESSO=2

processo=xxxyyyzzz  # Si usa un processo inesistente.
# Solo a scopo dimostrativo...
# ... con questo script non si vuole terminare nessun processo in esecuzione.
#
# Se però voleste, per esempio, usarlo per scollegarvi da Internet, allora
#     processo=pppd

t=`pidof $processo` # Cerca il pid (id di processo) di $processo.
#  Il pid è necessario a 'kill' (non si può usare 'kill' con 
#+ il nome del programma).

if [ -z "$t" ]      # Se il processo non è presente, 'pidof' restituisce null.
then
  echo "Il processo $processo non è in esecuzione."
  echo "Non è stato terminato alcun processo."
  exit $NESSUNPROCESSO
fi  

kill $t             # Potrebbe servire 'kill -9' per un processo testardo.

#  Qui sarebbe necessaria una verifica, per vedere se il processo ha 
#+ acconsentito ad essere terminato.
#  Forse un altro " t=`pidof $processo` " oppure...


# L'intero script potrebbe essere sostituito da
#    kill $(pidof -x nome_processo)
# oppure
#        killall nome_processo
# ma non sarebbe stato altrettanto istruttivo.

exit 0
fuser

Identifica i processi (tramite il PID) che hanno accesso ad un dato file, serie di file o directory. Può anche essere invocato con l'opzione -k che serve a terminare quei determinati processi. Questo ha interessanti implicazioni per la sicurezza, specialmente negli script che hanno come scopo quello di evitare, agli utenti non autorizzati, l'accesso ai servizi di sistema.

bash$ fuser -u /usr/bin/vim
/usr/bin/vim:         3207e(bozo)



bash$ fuser -u /dev/null
/dev/null:            3009(bozo)  3010(bozo)  3197(bozo)  3199(bozo)
	      

fuser si rivela un'applicazione importante nel momento in cui si devono inserire o rimuovere fisicamente dispositivi di memorizzazione, come i CD ROM o le memorie flash USB. Talvolta umount fallisce con il messaggio d'errore device is busy. Questo sta ad indicare che qualche utente e/o processo(i) hanno accesso a quel dispositivo. Un fuser -um /dev/nome_dispositivo vi rivelerà il mistero, così che possiate terminare tutti i processi coinvolti.

bash$ umount /mnt/driveusb
umount: /mnt/driveusb: device is busy



bash$ fuser -um /dev/driveusb
/mnt/driveusb:        1772c(bozo)

bash$ kill -9 1772
bash$ umount /mnt/driveusb
	      

Il comando fuser, invocato con l'opzione -n identifica i processi che hanno accesso ad una determinata porta. Si rivela particolarmente utile in abbinamento con nmap.

root# nmap localhost.localdomain
PORT     STATE SERVICE
25/tcp   open  smtp



root# fuser -un tcp 25
25/tcp:               2095(root)

root# ps ax | grep 2095 | grep -v grep
2095 ?        Ss     0:00 sendmail: accepting connections
	      

cron

Programma schedulatore d'amministrazione che esegue determinati compiti, quali pulire e cancellare i file di log di sistema ed aggiornare il database slocate. È la versione superutente di at (sebbene ogni utente possa avere il proprio file crontab che può essere modificato con il comando crontab). Viene posto in esecuzione come demone ed esegue quanto specificato in /etc/crontab

Nota

Alcune distribuzioni Linux eseguono crond, la versione cron di Matthew Dillon.

Controllo di processo e boot

init

Il comando init è il genitore di tutti i processi. Richiamato nella parte finale della fase di boot, init determina il runlevel del sistema com'è specificato nel file /etc/inittab. Viene invocato per mezzo del suo alias telinit e solo da root.

telinit

Link simbolico a init, rappresenta il mezzo per modificare il runlevel del sistema che, di solito, si rende necessario per ragioni di manutenzione dello stesso o per riparazioni d'emergenza del filesystem. Può essere invocato solo da root. Questo comando è potenzialmente pericoloso - bisogna essere certi di averlo ben compreso prima di usarlo!

runlevel

Mostra il corrente e ultimo runlevel, ovvero se il sistema è stato fermato (runlevel 0), se si trova in modalità utente singolo (1), in modalità multi-utente (2 o 3), in X Windows (5) o di riavvio (6). Questo comando ha accesso al file /var/run/utmp.

halt, shutdown, reboot

Serie di comandi per arrestare il sistema, solitamente prima dello spegnimento della macchina.

service

Avvia o arresta un servizio di sistema. Gli script di avvio (startup) presenti in /etc/init.d e in /etc/rc.d usano questo comando per attivare i servizi nella fase di boot.

root# /sbin/service iptables stop
Flushing firewall rules:                                   [  OK  ]
Setting chains to policy ACCEPT: filter                    [  OK  ]
Unloading iptables modules:                                [  OK  ]
	      

Rete

ifconfig

Utility per la configurazione e regolazione dell'interfaccia di rete.

bash$ ifconfig -a
lo        Link encap:Local Loopback
           inet addr:127.0.0.1  Mask:255.0.0.0
           UP LOOPBACK RUNNING  MTU:16436  Metric:1
           RX packets:10 errors:0 dropped:0 overruns:0 frame:0
           TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
           collisions:0 txqueuelen:0
           RX bytes:700 (700.0 b)  TX bytes:700 (700.0 b)

ifconfig viene usato molto spesso in fase di boot per impostare le interfacce, o per disabilitarle in caso di riavvio.

# Frammenti di codice dal file /etc/rc.d/init.d/network

# ...

# Controlla se la rete è attiva.
[ ${NETWORKING} = "no" ] && exit 0

[ -x /sbin/ifconfig ] || exit 0

# ...

for i in $interfaces ; do
  if ifconfig $i 2>/dev/null | grep -q "UP" >/dev/null 2>&1 ; then
    action "L'interfaccia $i non è attiva: " ./ifdown $i boot
  fi
#  L'opzione "-q" di "grep", che è una specifica GNU, significa 
#+ "quiet", cioè, non produce output. 
#  Quindi, redirigere l'output in /dev/null non è strettamente necessario.
       
# ...

echo "Attualmente sono attivi questi dispositivi:"
echo `/sbin/ifconfig | grep ^[a-z] | awk '{print $1}'`
#                            ^^^^^  
#           si dovrebbe usare il quoting per evitare il globbing.
#  Anche le forme seguenti vanno bene.
#    echo $(/sbin/ifconfig | awk '/^[a-z]/ { print $1 })'
#    echo $(/sbin/ifconfig | sed -e 's/ .*//')
#  Grazie, S.C. per i commenti aggiuntivi.

Vedi anche Esempio 29-6.

iwconfig

È il comando predisposto per la configurazione di una rete wireless. È l'equivalente wireless del precedente ifconfig, .

ip

Versatile utility per l'impostazione, modifica e analisi di reti IP (Internet Protocol) e dei relativi dispositivi. Questo comando fa parte del pacchetto iproute2.

bash$ ip link show
1: lo: <LOOPBACK,UP> mtu 16436 qdisc noqueue 
     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast qlen 1000
     link/ether 00:d0:59:ce:af:da brd ff:ff:ff:ff:ff:ff
 3: sit0: <NOARP> mtu 1480 qdisc noop 
     link/sit 0.0.0.0 brd 0.0.0.0
						
						
bash$ ip route list
169.254.0.0/16 dev lo  scope link
	  

Oppure, in uno script:

#!/bin/bash
# Script di Juan Nicolas Ruiz
# Usato per gentile concessione.

# Impostazione (e arresto) di un tunnel GRE.


# --- avvio-tunnel.sh ---

IP_LOCALE="192.168.1.17"
IP_REMOTO="10.0.5.33"
ALTRE_IFACCE="192.168.0.100"
RETE_REMOTA="192.168.3.0/24"

/sbin/ip tunnel add netb mode gre remote $IP_REMOTO \
  local $IP_LOCALE ttl 255
/sbin/ip addr add $ALTRE_IFACCE dev netb
/sbin/ip link set netb up
/sbin/ip route add $RETE_REMOTA dev netb

exit 0  #############################################

# --- arresto-tunnel.sh ---

RETE_REMOTA="192.168.3.0/24"

/sbin/ip route del $RETE_REMOTA dev netb
/sbin/ip link set netb down
/sbin/ip tunnel del netb

exit 0

route

Mostra informazioni, o permette modifiche, alla tabella di routing del kernel.

bash$ route
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
pm3-67.bozosisp *               255.255.255.255 UH       40 0          0 ppp0
127.0.0.0       *               255.0.0.0       U        40 0          0 lo
default         pm3-67.bozosisp 0.0.0.0         UG       40 0          0 ppp0
	      

chkconfig

Verifica la configurazione di rete. Il comando elenca e gestisce i servizi di rete presenti nella directory /etc/rc?.d avviati durante il boot.

Trattandosi dell'adattamento fatto da Red Hat Linux dell'originario comando IRIX, chkconfig potrebbe non essere presente nell'installazione di base di alcune distribuzioni Linux.

bash$ chkconfig --list
atd             0:off   1:off   2:off   3:on    4:on    5:on    6:off
rwhod           0:off   1:off   2:off   3:off   4:off   5:off   6:off
...
	      

tcpdump

"Sniffa" i pacchetti di rete. È uno strumento per analizzare e risolvere problemi di traffico sulla rete per mezzo del controllo delle intestazioni di pacchetto che verificano criteri specifici.

Analizza gli ip dei pacchetti in transito tra gli host bozoville e caduceus:

bash$ tcpdump ip host bozoville and caduceus
	      

Naturalmente, l'output di tcpdump può essere verificato con alcune delle già trattate utility per l'elaborazione del testo.

Filesystem

mount

Monta un filesystem, solitamente di un dispositivo esterno, come il floppy disk o il CDROM. Il file /etc/fstab fornisce un utile elenco dei filesystem, partizioni e dispositivi disponibili, con le relative opzioni, che possono essere montati automaticamente o manualmente. Il file /etc/mtab mostra le partizioni e i filesystem attualmente montati (compresi quelli virtuali, come /proc).

mount -a monta tutti i filesystem e le partizioni elencate in /etc/fstab, ad eccezione di quelli con l'opzione noauto. Al boot uno script di avvio, presente in /etc/rc.d (rc.sysinit o qualcosa di analogo), invoca questo comando per montare tutto quello che deve essere montato.

mount -t iso9660 /dev/cdrom /mnt/cdrom
# Monta il CDROM
mount /mnt/cdrom
# Scorciatoia, se /mnt/cdrom è elencato in /etc/fstab

Questo versatile comando può persino montare un comune file su un dispositivo a blocchi, ed il file si comporterà come se fosse un filesystem. mount riesce a far questo associando il file ad un dispositivo di loopback. Una sua possibile applicazione può essere quella di montare ed esaminare un'immagine ISO9660 prima di masterizzarla su un CDR. [3]

Esempio 16-7. Verificare un'immagine CD

# Da root...

mkdir /mnt/cdtest  # Prepara un punto di mount, nel caso non esistesse.

mount -r -t iso9660 -o loop cd-image.iso /mnt/cdtest   # Monta l'immagine.
#                  l'opzione "-o loop" equivale a "losetup /dev/loop0"
cd /mnt/cdtest     # Ora verifica l'immagine.
ls -alR            # Elenca i file della directory.
                   # Eccetera.
umount

Smonta un filesystem attualmente montato. Prima di rimuovere fisicamente un floppy disk o un CDROM precedentemente montato, il dispositivo deve essere smontato, altrimenti si potrebbe ottenere, come risultato, la corruzione del filesystem.

umount /mnt/cdrom
# Ora potete premere il tasto eject e rimuovere in tutta sicurezza il disco.

Nota

L'utility automount, se correttamente installata, può montare e smontare i floppy disk e i CDROM nel momento in cui vi si accede o in fase di rimozione. Questa potrebbe, comunque, causare problemi sui portatili con dispositivi floppy e CDROM intercambiabili.

gnome-mount

Le nuove distribuzioni Linux deprecano mount e umount. L'erede, per montare da riga di comando i dispositivi di memoria di massa rimovibili, è gnome-mount. Usato con l'opzione -d monta un dispositivo elencato nella directory /dev.

Per esempio, per montare una memoria flash USB:

bash$ gnome-mount -d /dev/sda1
gnome-mount 0.4
						
						
bash$ df
. . .
 /dev/sda1                63584     12034     51550  19% /media/disk

sync

Forza la scrittura immediata di tutti i dati aggiornati dai buffer all'hard disk (sincronizza l'HD con i buffer). Sebbene non strettamente necessario, sync assicura l'amministratore di sistema, o l'utente, che i dati appena modificati sopravviveranno ad un'improvvisa mancanza di corrente. Una volta, un sync; sync (due volte, tanto per essere assolutamente sicuri) era un'utile misura precauzionale prima del riavvio del sistema.

A volte può essere desiderabile una pulizia immediata dei buffer, come nel caso della cancellazione di sicurezza di un file (vedi Esempio 15-55) o quando le luci di casa incominciano a tremolare.

losetup

Imposta e configura i dispositivi di loopback.

Esempio 16-8. Creare un filesystem in un file

DIMENSIONE=1000000  # 1 mega

head -c $DIMENSIONE < /dev/zero > file  #  Imposta il file alla
                                        #+ dimensione indicata.
losetup /dev/loop0 file                 #  Lo imposta come dispositivo 
                                        #+ di loopback.
mke2fs /dev/loop0                       # Crea il filesystem.
mount -o loop /dev/loop0 /mnt           # Lo monta.

# Grazie, S.C.
mkswap

Crea una partizione o un file di scambio. L'area di scambio dovrà successivamente essere abilitata con swapon.

swapon, swapoff

Abilita/disabilita una partizione o un file di scambio. Questi comandi vengono solitamente eseguiti in fase di boot o di arresto del sistema.

mke2fs

Crea un filesystem Linux di tipo ext2. Questo comando deve essere invocato da root.

Esempio 16-9. Aggiungere un nuovo hard disk

#!/bin/bash

# Aggiunge un secondo hard disk al sistema.
# Configurazione software. Si assume che l'hardware sia già montato sul PC.
# Da un articolo dell'autore di questo libro.
# Pubblicato sul nr. 38 di "Linux Gazette", http://www.linuxgazette.com.

ROOT_UID=0     # Lo script deve essere eseguito da root.
E_NONROOT=67   # Errore d'uscita non-root.

if [ "$UID" -ne "$ROOT_UID" ]
then
  echo "Devi essere root per eseguire questo script."
  exit $E_NONROOT
fi  

#  Da usare con estrema attenzione!
#  Se qualcosa dovesse andare storto, potreste cancellare irrimediabilmente 
#+ il filesystem corrente.


NUOVODISCO=/dev/hdb        # Si assume che sia libero /dev/hdb. Verificate!
MOUNTPOINT=/mnt/nuovodisco # Oppure scegliete un altro punto di montaggio.

fdisk $NUOVODISCO
mke2fs -cv $NUOVODISCO1    #  Verifica i blocchi difettosi visualizzando un 
                           #+ output dettagliato.
#  Nota:    /dev/hdb1, *non* /dev/hdb!
mkdir $MOUNTPOINT
chmod 777 $MOUNTPOINT     # Rende il nuovo disco accessibile a tutti gli utenti.


# Ora, una verifica...
# mount -t ext2 /dev/hdb1 /mnt/nuovodisco
# Provate a creare una directory.
# Se l'operazione riesce, smontate la partizione e procedete.

# Passo finale:
# Aggiungete la riga seguente in /etc/fstab.
# /dev/hdb1  /mnt/nuovodisco  ext2  defaults  1 1

exit 0

Vedi anche Esempio 16-8 e Esempio 28-3.

tune2fs

Serve per la taratura di un filesystem di tipo ext2. Può essere usato per modificare i parametri del filesystem, come il numero massimo dei mount. Deve essere invocato da root.

Avvertimento

Questo è un comando estremamente pericoloso. Si usa a proprio rischio, perché si potrebbe inavvertitamente distruggere il filesystem.

dumpe2fs

Fornisce (elenca allo stdout) informazioni dettagliatissime sul filesystem. Dev'essere invocato da root.

root# dumpe2fs /dev/hda7 | grep 'ount count'
dumpe2fs 1.19, 13-Jul-2000 for EXT2 FS 0.5b, 95/08/09
Mount count:              6
Maximum mount count:      20
hdparm

Elenca o modifica i parametri dell'hard disk. Questo comando va invocato da root e può risultare pericoloso se usato in modo maldestro.

fdisk

Crea o modifica la tabella delle partizioni di un dispositivo per la registrazione dei dati, di solito un hard disk. Dev'essere invocato da root.

Avvertimento

Si utilizzi questo comando con estrema attenzione. Se qualcosa dovesse andare storto si potrebbe distruggere il filesystem.

fsck, e2fsck, debugfs

Serie di comandi per la verifica, riparazione e "debugging" del filesystem.

fsck: front end per la verifica di un filesystem UNIX (può invocare altre utility). Il filesystem preimpostato, generalmente, è di tipo ext2.

e2fsck: esegue la verifica di un filesystem di tipo ext2.

debugfs: per il "debugging" di un filesystem di tipo ext2. Uno degli usi di questo versatile, ma pericoloso, comando è quello di (cercare di) recuperare i file cancellati. Solo per utenti avanzati!

Attenzione

Tutti i precedenti comandi dovrebbero essere invocati da root e, se usati in modo scorretto, potrebbero danneggiare o distruggere il filesystem.

badblocks

Verifica i blocchi difettosi (difetti fisici) di un dispositivo di registrazione dati. Questo comando viene usato per formattare un nuovo hard disk installato o per verificare l'integrità di un dispositivo per il backup. [4] Ad esempio, badblocks /dev/fd0 verifica il floppy disk.

Il comando badblocks può essere invocato o in modalità distruttiva (sovrascrittura di tutti i dati) o non distruttiva, in sola lettura. Se l'utente root possiede il dispositivo che deve essere verificato, com'è di solito il caso, allora è root che deve invocare questo comando.

lsusb, usbmodules

Il comando lsusb elenca tutti i bus USB (Universal Serial Bus) e i dispositivi ad essi collegati.

Il comando usbmodules visualizza le informazioni sui moduli dei dispositivi USB collegati.

bash$ lsusb
 Bus 001 Device 001: ID 0000:0000
 Device Descriptor:
   bLength                18
   bDescriptorType         1
   bcdUSB               1.00
   bDeviceClass            9 Hub
   bDeviceSubClass         0
   bDeviceProtocol         0
   bMaxPacketSize0         8
   idVendor           0x0000
   idProduct          0x0000
   
   . . .
	      

lspci

Elenca i bus pci presenti.

bash$ lspci
00:00.0 Host bridge: Intel Corporation 82845 845 (Brookdale) Chipset Host Bridge (rev 04)
 00:01.0 PCI bridge: Intel Corporation 82845 845 (Brookdale) Chipset AGP Bridge (rev 04)
 00:1d.0 USB Controller: Intel Corporation 82801CA/CAM USB (Hub #1) (rev 02)
 00:1d.1 USB Controller: Intel Corporation 82801CA/CAM USB (Hub #2) (rev 02)
 00:1d.2 USB Controller: Intel Corporation 82801CA/CAM USB (Hub #3) (rev 02)
 00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev 42)
							
 . . .
	  	  

mkbootdisk

Crea un dischetto di boot che può essere usato per avviare il sistema se, per esempio, il MBR (master boot record) si è corrotto. Il comando mkbootdisk, in realtà, è uno script Bash scritto da Erik Troan che si trova nella directory /sbin.

chroot

Cambia la directory ROOT (CHange ROOT). Normalmente i percorsi dei comandi relativi a /, la directory root predefinita, vengono forniti da $PATH. Questo comando cambia la directory root predefinita in un'altra (che diventa anche la directory di lavoro corrente). È utile per motivi di sicurezza, ad esempio quando l'amministratore di sistema desidera limitare l'attività di certi utenti, come quelli che stanno usando telnet, ad una porzione sicura del filesystem (talvolta si fa riferimento a questa azione come "confinare un utente in una prigione, o gabbia, chroot"). Si noti che dopo un chroot l'originario percorso degli eseguibili di sistema non è più valido.

Il comando chroot /opt dovrebbe cambiare il riferimento da /usr/bin in /opt/usr/bin. Allo stesso modo, chroot /aaa/bbb /bin/ls dovrebbe redirigere le successive chiamate di ls a /aaa/bbb come directory base, al posto di / com'è normalmente il caso. La riga alias XX 'chroot /aaa/bbb ls' inserita nel file ~/.bashrc di un utente, delimita la porzione di filesystem (/aaa/bbb) sulla quale quell'utente può eseguire il comando "XX".

Il comando chroot è anche utile durante l'esecuzione da un dischetto di boot d'emergenza (chroot a /dev/fd0), o come opzione di lilo in caso di ripristino dopo un crash del sistema. Altri usi comprendono l'installazione da un filesystem diverso (un'opzione rpm) o l'esecuzione di un filesystem in sola lettura da CDROM. Va invocato solo da root ed usato con attenzione.

Attenzione

Potrebbe rendersi necessario copiare alcuni file di sistema nella directory indicata a chroot perché, dopo, non ci si potrà più basare sull'usuale variabile $PATH.

lockfile

Questa utility fa parte del pacchetto procmail (www.procmail.org). Serve a creare un file lock, un semaforo che controlla l'accesso ad un file, ad un dispositivo o ad una risorsa. Il file lock sta ad indicare che quel particolare file, dispositivo o risorsa è utilizzato da un determinato processo ("busy") e questo consente un accesso limitato (o nessun accesso) ad altri processi.

lockfile /home/bozo/lockfiles/$0.lock
# Crea un file lock, protetto in scrittura, con lo stesso nome dello script.

I file lock vengono utilizzati, ad esempio, per proteggere le cartelle di posta di sistema da modifiche fatte simultaneamente da più utenti, per indicare che si è avuto accesso ad una porta modem o per mostrare che un'istanza di Netscape sta usando la sua cache. È possibile, per mezzo di script, accertarsi dell'esistenza di un file lock creato da un certo processo, per verificare se quel processo è ancora in esecuzione. Si noti che se uno script cerca di creare un file lock già esistente, lo script, probabilmente, si bloccherà.

Normalmente, le applicazioni creano e verificano i file lock nella directory /var/lock. [5] Uno script può accertarsi della presenza di un file lock con qualcosa di simile a quello che segue.

nomeapplicazione=xyzip
# L'applicazione "xyzip" ha creato il file lock "/var/lock/xyzip.lock".

if [ -e "/var/lock/$nomeapplicazione.lock" ]
then   #+ Evita ad altri programmi & script
       #  l'accesso a file/risorse usate da xyzip.
  ...

flock

flock è molto meno utile di lockfile. Imposta un lock d'"avvertimento" su un file, quindi esegue un comando. Questo impedisce ad un altro processo di impostare un lock su quel file finché il comando specificato non ha terminato il proprio compito.

flock $0 cat $0 > filelock__$0
#  Imposta un lock sullo script in cui appare la riga precedente,
#+ per la durata della visualizzazione dello script allo stdout.

Nota

Al contrario di lockfile, flock non crea automaticamente un file lock.

mknod

Crea file di dispositivo a blocchi o a caratteri (potrebbe essere necessario per l'installazione di nuovo hardware sul sistema). L'utility MAKEDEV possiede tutte le funzionalità di mknod ed è più facile da usare.

MAKEDEV

Utility per la creazione di file di dispositivo. Deve essere eseguita da root e ci si deve trovare nella directory /dev. È una specie di versione avanzata di mknod.

tmpwatch

Cancella automaticamente i file a cui non si è acceduto da un determinato periodo di tempo. È invocato, di solito, da crond per cancellare vecchi file di log.

Backup

dump, restore

Il comando dump è un'elaborata utility per il backup del filesystem e viene generalmente usata su installazioni e reti di grandi dimensioni. [6] Legge le partizioni del disco e scrive un file di backup in formato binario. I file di cui si deve eseguire il backup possono essere salvati su dispositivi di registrazione più vari, compresi dischi e dispositivi a nastro. Il comando restore ripristina i backup effettuati con dump.

fdformat

Esegue una formattazione a basso livello di un dischetto (/dev/fd0*).

Risorse di sistema

ulimit

Imposta un limite superiore all'uso delle risorse di sistema. Viene solitamente invocato con l'opzione -f, che imposta la dimensione massima del file (ulimit -f 1000 limita la dimensione massima dei file a 1 mega). L'opzione -t imposta il limite dei file core (ulimit -c 0 elimina i file core). Di norma, il valore di ulimit dovrebbe essere impostato nel file /etc/profile e/o ~/.bash_profile (vedi Appendice G).

Importante

Un uso giudizioso di ulimit può proteggere il sistema contro una temibile bomba fork.

#!/bin/bash
# Script a solo scopo illustrativo.
# L'esecuzione è a vostro rischio -- vi BLOCCHERÀ il sistema.

while true  #  Ciclo infinito.
do
  $0 &      #  Lo script invoca se stesso . . .
            #+ genera il processo un numero infinito di volte . . .
            #+ finché il sistema non si blocca a seguito
            #+ dell'esaurimento di tutte le risorse.
done        #  Questo è il famigerato scenario dell'"apprendista stregone".

exit 0      #  Non esce qui, perché questo script non terminerà mai.

La riga ulimit -Hu XX (dove XX è il limite del processo utente), inserita nel file /etc/profile, avrebbe fatto abortire lo script appena lo stesso avesse superato il suddetto limite.

quota

Visualizza le quote disco dell'utente o del gruppo.

setquota

Imposta, da riga di comando, le quote disco di un utente o di un gruppo.

umask

Maschera per per l'impostazione dei permessi sui file dell'utente. Limita gli attributi predefiniti dei file di un particolare utente. Tutti i file creati da quell'utente otterranno gli attributi specificati con umask. Il valore (ottale) passato ad umask definisce i permessi disabilitati del file. Per esempio, umask 022 fa sì che i nuovi file avranno al massimo i permessi 755 (777 NAND 022). [7] Naturalmente l'utente potrà, successivamente, modificare gli attributi di file particolari con chmod. È pratica corrente impostare il valore di umask in /etc/profile e/o ~/.bash_profile (vedi Appendice G).

Esempio 16-10. Usare umask per celare l'output di un file da occhi indagatori

#!/bin/bash
#  rot13a.sh: Uguale allo script "rot13.sh", 
#+ ma scrive l'output in un file "sicuro".

# Utilizzo: ./rot13a.sh nomefile
# o         ./rot13a.sh <nomefile
# oppure    ./rot13a.sh e fornire l'input da tastiera (stdin)

umask 177               #  Maschera per la creazione del file.
                        #  I file creati da questo script
                        #+ avranno i permessi impostati a 600.

FILEOUT=cifrato.txt     #  L'output è inserito nel file "cifrato.txt"
                        #+ che può essere letto/scritto solo
                        #  da chi invoca lo scrip (o da root).

cat "$@" | tr 'a-zA-Z' 'n-za-mN-ZA-M' > $FILEOUT 
#    ^^Input dallo stdin o da un file.^^^^^^^^^^ Output rediretto in un file. 

exit 0
rdev

Fornisce informazioni o esegue modifiche sulla partizione di root, sullo spazio di scambio (swap) o sulle modalità video. Le sue funzionalità sono state, in genere, superate da lilo, ma rdev resta utile per impostare un ram disk. Questo comando, se usato male, è pericoloso.

Moduli

lsmod

Elenca i moduli del kernel installati.

bash$ lsmod
Module                  Size  Used by
autofs                 9456   2 (autoclean)
opl3                  11376   0
serial_cs              5456   0 (unused)
sb                    34752   0
uart401                6384   0 [sb]
sound                 58368   0 [opl3 sb uart401]
soundlow                464   0 [sound]
soundcore              2800   6 [sb sound]
ds                     6448   2 [serial_cs]
i82365                22928   2
pcmcia_core           45984   0 [serial_cs ds i82365]
	      

Nota

Le stesse informazioni si ottengono con cat /proc/modules.

insmod

Forza l'installazione di un modulo del kernel (quando è possibile è meglio usare modprobe). Deve essere invocato da root.

rmmod

Forza la disinstallazione di un modulo del kernel. Deve essere invocato da root.

modprobe

Carica i moduli ed è, solitamente, invocato automaticamente in uno script di avvio. Deve essere invocato da root.

depmod

Crea il file delle dipendenze dei moduli. Invocato di solito da uno script di avvio.

modinfo

Visualizza informazioni su un modulo caricabile.

bash$ modinfo hid
 filename:    /lib/modules/2.4.20-6/kernel/drivers/usb/hid.o
 description: "USB HID support drivers"
 author:      "Andreas Gal, Vojtech Pavlik <vojtech@suse.cz>"
 license:     "GPL"
	      

Miscellanea

env

Esegue un programma, o uno script, impostando o modificando determinate variabili d'ambiente (senza dover modificare l'intero ambiente del sistema). [nomevariabile=xxx] consente di modificare la variabile d'ambiente nomevariabile per la durata dello script. Se non viene specificata nessuna opzione, questo comando elenca le impostazioni di tutte le variabili d'ambiente.

Nota

In Bash e in altre shell derivate dalla Bourne, è possibile impostare le variabili nell'ambiente di un singolo comando.

var1=valore1 var2=valore2 comandoXXX
# $var1 e $var2 vengono impostate solo nell'ambiente di 'comandoXXX'.

Suggerimento

È possibile usare env nella prima riga di uno script (la c.d.riga "sha-bang") quando non si conosce il percorso della shell o dell'interprete.

#! /usr/bin/env perl

print "Questo script Perl verrà eseguito,\n";
print "anche quando non sai dove si trova l'interprete Perl.\n";

# Ottimo per la portabilità degli script su altre piattaforme,
# dove i binari Perl potrebbero non essere dove ci aspettiamo.
# Grazie, S.C.

ldd

Mostra le dipendenze delle librerie condivise di un file eseguibile.

bash$ ldd /bin/ls
libc.so.6 => /lib/libc.so.6 (0x4000c000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)
watch

Esegue un comando ripetutamente, ad intervalli di tempo specificati.

Gli intervalli preimpostati sono di due secondi, ma questo valore può essere modificato mediante l'opzione -n.

watch -n 5 tail /var/log/messages
#  Visualizza la parte finale del file di log di sistema /var/log/messages
#+ ogni cinque secondi.

Nota

Sfortunatamente, collegare con una pipe l'output del comando watch a grep non funziona.

strip

Rimuove i riferimenti simbolici per il "debugging" da un binario eseguibile. Questo diminuisce la sua dimensione, ma rende il "debugging" impossibile.

Questo comando si trova spesso nei Makefile, ma raramente in uno script di shell.

nm

Elenca i riferimenti simbolici, se non tolti con strip, presenti in un binario compilato.

rdist

Client per la distribuzione remota di file: sincronizza, clona o esegue il backup di un filesystem su un server remoto.

16.1. Analisi di uno script di sistema

Utilizzando le conoscenze fin qui conseguite sui comandi d'amministrazione, ora si passa all'esame di uno script di sistema. Uno dei più brevi e più semplici da capire è "killall" [8] che è utilizzato per sospendere i processi nella fase di arresto del sistema.

Esempio 16-11. killall, da /etc/rc.d/init.d

#!/bin/sh

# --> I commenti aggiunti dall'autore del libro sono indicati con "# -->".

# --> Questo fa parte del pacchetto di script 'rc'
# --> di Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>

# --> Sembra che questo particolare script sia specifico di Red Hat
# --> (potrebbe non essere presente in altre distribuzioni).

#  Bring down all unneeded services that are still running (there shouldn't 
#+ be any, so this is just a sanity check)

for i in /var/lock/subsys/*; do
        # --> Ciclo standard for/in, ma poiché "do" è posto sulla stessa riga,
        # --> è necessario aggiungere il ";".
        # Check if the script is there.
        [ ! -f $i ] && continue
        # --> Ecco un uso intelligente di una "lista and", equivale a:
        # --> if [ ! -f "$i" ]; then continue

        # Get the subsystem name.
        subsys=${i#/var/lock/subsys/}
        # --> Imposta la variabile, in questo caso, al nome del file.
        # --> È l'equivalente esatto di subsys=`basename $i`.

        # -->  Viene ricavato dal nome del file lock (se esiste un file lock
        # -->+ che rappresenta la prova che il processo è in esecuzione).
        # -->  Vedi la precedente voce "lockfile".


        # Bring the subsystem down.
        if [ -f /etc/rc.d/init.d/$subsys.init ]; then
            /etc/rc.d/init.d/$subsys.init stop
        else
            /etc/rc.d/init.d/$subsys stop
        # -->  Sospende i job ed i demoni in esecuzione.
        # -->  E' da notare che "stop" è un parametro posizionale,
        # -->+ non un builtin di shell.
        fi
done

Non è poi così difficile. Tranne che per una piccola ed insolita impostazione di variabile, non vi è niente che già non si conosca.

Esercizio 1. Si analizzi lo script halt in /etc/rc.d/init.d. È leggermente più lungo di killall, ma concettualmente simile. Si faccia una copia dello script nella directory personale e con essa si eseguano delle prove ( non va eseguito da root). Si effettui un'esecuzione simulata con le opzioni -vn (sh -vn nomescript). Si aggiungano commenti dettagliati. Si sostituiscano i comandi "action" con "echo".

Esercizio 2. Si dia un'occhiata ad alcuni degli script più complessi presenti in /etc/rc.d/init.d. Si veda se si riesce a comprendere parti di questi script. Per l'analisi, si segua la procedura spiegata nell'esercizio precedente. Per alcuni ulteriori approfondimenti si potrebbe anche esaminare il file sysvinitfiles in /usr/share/doc/initscripts-?.?? che fa parte della documentazione "initscripts".

Note

[1]

Questo è il caso su una macchina Linux o un sistema UNIX su cui è attiva la gestione delle quote del/dei disco/hi.

[2]

Il comando userdel non funziona se l'utente che deve essere cancellato è ancora connesso.

[3]

Per maggiori dettagli sulla registrazione dei CDROM, vedi l'articolo di Alex Withers, Creating CDs, nel numero dell'Ottobre 1999 di Linux Journal.

[4]

Anche il comando mke2fs con l'opzione -c esegue la verifica dei blocchi difettosi.

[5]

Dal momento che solo root possiede i permessi di scrittura sulla directory /var/lock, uno script di un utente normale non può crearvi un file lock.

[6]

Gli operatori su sistemi Linux in modalità utente singolo, generalmente preferiscono qualcosa si più semplice per i backup, come tar.

[7]

NAND è l'operatore logico not-and. La sua azione è paragonabile ad una sottrazione.

[8]

Lo script di sistema killall non deve essere confuso con il comando killall presente in /usr/bin.