Gentoo Logo

Disclaimer : La versione originale di questo articolo è stata pubblicata da IBM developerWorks ed è di proprietà di Westtech Information Services. Questo documento è una versione aggiornata dell'articolo originale, e contiene numerosi miglioramenti apportati dal Gentoo Linux Documentation team.
Questo documento non è mantenuto attivamente.


Preparazione all'esame per la Certificazione LPI 101 (release 2), Parte 2

Indice:

1.  Prima di cominciare

Riguardo a questa introduzione

Benvenuti in "Amministrazione di base", la seconda di quattro brevi guide concepite per preparare il lettore all'esame 101 del Linux Professional Institute. In questa breve guida, al lettore sarà mostrato come usare le espressioni regolari nella la ricerca di file per modelli di testo. Poi, verrà introdotto al Filesystem Hierarchy Standard (FSH) o Gerarchia predefinita per Filesystem e quindi sarà mostrato come individuare file nel proprio sistema. Ancora, verrà illustrato come avere pieno controllo dei processi in Linux eseguendoli in background, recuperando la lista dei processi, slegando processi dal terminale e tanto ancora. Di seguito, sarà data una fugace introduzione alle pipeline della shell, le ridirezione e i comandi per l'elaborazione del testo. Infine, il lettore sarà introdotto ai moduli del kernel Linux.

Questa breve guida in particolare (Parte 2) è indicata per coloro che hanno una buona conoscenza di base riguardo bash e vogliono ricevere una solida introduzione alle tecniche di base per l'amministrazione in Linux. Per chi fosse nuovo di Linux, si raccomanda di completare la Parte 1 di questa serie di brevi guide prima di andare avanti. Per tanti, gran parte di questo materiale sarà nuovo ma molti utenti Linux con più esperienza possono trovare questa breve guida un bel modo per affinare le loro abilità di base nell'amministrazione in Linux.

Per chi fosse già in possesso della versione di rilascio 1 di questa guida per altre ragioni oltre alla preparazione dell'esame del LPI, probabilmente non sarà necessario prendere anche questa. Comunque, se si pianifica di sostenere gli esami, dovrebbe essere decisamente presa in considerazione la lettura di questa versione rivista della guida.

Riguardo agli autori

Residente in Albuquerque, New Mexico, Daniel Robbins è l'Architetto Capo di Gentoo Linux, un'avanzata meta distribuzione Linux basata su sorgenti. Ha anche scritto articoli, brevi guide e suggerimenti nell'area dedicata a Linux dell'IBM developerWorks e per l'Intel Developer Services e ha anche preso parte come autore di contributi per diversi libri, incluso Samba Unleashed e SuSE Linux Unleashed. Daniel si diverte passando il proprio tempo con sua moglie, Mary, e sua figlia, Hadassah. È possibile contattare Daniel all'indirizzo Daniel Robbins.

Chris Houser, conosciuto dagli amici come "Chouser", è diventato un sostenitore di UNIX fin dal 1994 quando ha preso parte al gruppo di amministrazione delle reti scientifiche di calcolatori alla Taylor University nell'Indiana, dove ha conseguito la sua laurea in Scienze Informatiche e Matematiche. Fino da allora, ha continuato a lavorare nella programmazione di applicazioni Web, sviluppo di interfacce utente, supporto professionale al software video e ora alla programmazione di driver per dispositivi Tru64 UNIX alla Compaq. Ha anche contribuito a diversi progetti di software libero, più recentemente a Gentoo Linux. Vive con sua moglie e due gatti in New Hampshire. È possibile contattare Chris a chouser@gentoo.org.

Aron Griffis è diplomato alla Taylor University con una laurea in Scienze Informatiche e un premio che dichiara, "Futuro Fondatore di un utopistico gruppo UNIX". Lavorando verso questo obiettivo, Aron è impiegato presso Compaq scrivendo driver di rete per TRU64UNIX e spende il suo tempo libero accordando il piano o sviluppando Gentoo Linux. Vive con sua moglie Amy (anche lei ingegnere UNIX) in Nashua, New Hampshire.

2.  Espressioni regolari

Cosa sono le espressioni regolari

Una espressione regolare (anche chiamata "regex" o "regexp") è una sintassi speciale usata per descrivere modelli di testo (o pattern). Su sistemi Linux, le espressioni regolari sono di solito usate per trovare modelli di testo così come effettuare operazioni di search-and-replace (cerca e sostituisci) su flussi di testo.

Confronto fra glob

Nel momento in cui si affronta l'argomento espressioni regolari, ci si accorge che la sintassi delle espressioni regolari assomiglia alla sintassi del "globbing" per nomi di file vista nella Parte 1. Comunque, non bisogna farsi distrarre da questo; la loro somiglianza è solo superficiale. Sia le espressioni regolari che i modelli di globbing per nomi di file, nonostante possano assomigliarsi, sono entità radicalmente diverse.

La semplice sotto stringa

Con cautela, sarà data un'occhiata all'elemento di base delle espressioni regolari, la semplice sotto stringa. Per fare questo, verrà usato grep, un comando che esamina il contenuto di un file alla ricerca di una particolare espressione regolare. Il comando grep stampa ogni linea che concorda con l'espressione regolate e ignora ogni linea discordante:

Codice 2.1: grep in azione

$ grep bash /etc/passwd
operator:x:11:0:operator:/root:/bin/bash
root:x:0:0::/root:/bin/bash
ftp:x:40:1::/home/ftp:/bin/bash

Sopra, il primo parametro di grep è un regex (espressione regolare, da regular expression); il secondo è il nome del file. grep legge ogni linea in /etc/passwd e applica la semplice sotto stringa regex di bash ad esse, cercando una corrispondenza. Se c'è un riscontro, grep stampa a video l'intera linea; altrimenti, la linea viene ignorata.

Capire la semplice sotto stringa

In genere, se si sta cercando una sotto stringa, basta specificare il testo alla lettera senza fornire alcune carattere "speciale". Le sole volte in cui esiste la necessità di fare qualcosa di speciale è laddove la propria sotto stringa contiene un +, ., *, [, ] o \, nel qual caso questi caratteri devono essere racchiusi fra apici e preceduti da una barra inversa. Di seguito alcuni esempi di semplici sotto stringhe come espressioni regolari:

  • /tmp (esamina alla ricerca della stringa letterale /tmp)
  • "\[box\]" (esamina alla ricerca della stringa letterale [box])
  • "\*funny\*" (esamina alla ricerca della stringa letterale *funny*)
  • "ld\.so" (esamina alla ricerca della stringa letterale ld.so)

Meta caratteri

Con le espressioni regolari, possono essere effettuate molte ricerche più complesse di quelle negli esempi visti sopra traendo vantaggio dai meta caratteri. Uno di questi meta caratteri è il . (un punto), che si combina con ogni carattere singolo:

Codice 2.2: Il meta carattere punto

$ grep dev.hda /etc/fstab
/dev/hda3       /               reiserfs        noatime,ro 1 1
/dev/hda1       /boot           reiserfs        noauto,noatime,notail 1 2
/dev/hda2       swap            swap            sw 0 0
#/dev/hda4      /mnt/extra      reiserfs        noatime,rw 1 1

In questo esempio, il testo letterale dev.hda non appare su nessuna delle linee in /etc/fstab. Tuttavia, grep non esaminerà il file cercando la stringa letterale dev.hda, ma il modello dev.hda. Bisogna ricordare che il . corrisponderà a qualsiasi singolo carattere. Come è possibile vedere, il meta carattere . ha funzionalità equivalenti a quelle del meta carattere ? nelle espansioni "glob".

Usare []

Se si desidera riscontrare un carattere in modo più specifico del ., è possibile usare [ e ] (parentesi quadre) per indicare un sotto insieme di caratteri che dei quale effettuare la corrispondenza:

Codice 2.3: Parentesi in azione

$ grep dev.hda[12] /etc/fstab
/dev/hda1       /boot           reiserfs        noauto,noatime,notail 1 2
/dev/hda2       swap            swap            sw 0 0

Come si nota, questa particolare caratteristica sintattica opera in modo identico a [] nell'espansione di nomi di file "glob". Ancora, questa è una delle cose delicate da imparare riguardo alle espressioni regolari -- la sintassi è simile ma non identica alla sintassi per l'espansione di nomi di file "glob", la quale spesso rende le regex leggermente più difficili da imparare.

Usare [^]

Il significato delle parentesi quadre può essere invertito inserendo un ^ immediatamente prima di [. In questo caso, le parentesi corrisponderanno ad ogni carattere che non è inserito nella lista all'interno di esse. Ancora, da notare l'uso di [^] con le espressioni regolari, ma [!] con globs:

Codice 2.4: Parentesi con negazione

$ grep dev.hda[^12] /etc/fstab
/dev/hda3       /               reiserfs        noatime,ro 1 1
#/dev/hda4      /mnt/extra      reiserfs        noatime,rw 1 1

Diversa sintassi

È importante osservare che la sintassi all'interno delle parentesi quadre è fondamentalmente diversa da quella presente in altri punti nelle espressioni regolari. Per esempio, se viene inserito un . all'interno delle parentesi quadre, permetterà a quest'ultime di effettuare una corrispondenza con il carattere letterale ., come negli esempi 1 e 2 sopra. In confronto, un letterale . fuori dalle parentesi quadre è interpretato come un meta carattere a meno che non presenti il prefisso \. Da ciò può essere tratto vantaggio per stampare una lista di tutte le linee in /etc/fstab che contengono la stringa letterale dev.hda, digitando:

Codice 2.5: Stampare letterali usando le parentesi

$ grep dev[.]hda /etc/fstab

In alternativa, è possibile digitare anche:

Codice 2.6: Stampare letterali usando il carattere di evasione

$ grep "dev\.hda" /etc/fstab

Nessuna delle espressioni regolari è possibile che riscontri ogni linea nel file /etc/fstab dell'utente.

Il meta carattere "*"

Alcuni meta caratteri non riscontrano niente di per sé, ma piuttosto modificano il significato del carattere precedente. Uno di questi meta caratteri è * (asterisco), che viene usato per indicare zero o più occorrenze ripetute del carattere precedente. Notare che questo comporta che l'* ha un significato diverso in una regex rispetto a quello visto per i glob. Di seguito alcuni esempi, per cui andrebbe fatta attenzione alle istanze dove queste regex riscontrano differenze dai glob:

  • ab*c comprende abbbbc ma non abqc (in un glob, sarebbero accettate entrambe le stringhe -- il lettore riesce a immaginarsi come?))
  • ab*c comprende abc ma non abbqbbc (ancora, in un glob, sarebbero riscontrate entrambe le stringhe)
  • ab*c comprende ac ma non cba (se in un glob, ac non sarebbe riscontrato e così neanche cba)
  • b[cq]*e comprende bqe e be (se in un glob, sarebbe stato compreso bqe ma non più be)
  • b[cq]*e comprende bccqqe ma non bccc (se in un glob, sarebbe stata accettata la prima ma non la seconda)
  • b[cq]*e comprende bqqcce ma non cqe (se in un glob, sarebbe stata riscontrata la prima ma non anche la seconda)
  • b[cq]*e comprende bbbeee (questo non sarebbe lo stesso con un glob)
  • .* accetterà ogni stringa (se in un glob, sarebbero state riscontrate solo stringhe che iniziassero con .)
  • foo.* comprenderà ogni stringa che comincia per foo (in un glob sarebbe stata accettata ogni stringa che cominciasse con i caratteri letterali con foo.)

Adesso, per una veloce ripasso mentale: la linea ac accetta la regex ab*c perché l'asterisco permette anche all'espressione precedente (b) di apparire zero volte. Ancora, è fondamentale notare che il meta carattere * delle regex è interpretato in maniera fondamentalmente diversa rispetto al carattere glob *.

Inizio e fine di una linea

Gli ultimi meta caratteri che verranno discussi in dettaglio qui sono i metacaratteri ^ e $, usati per indicare l'inizio e la fine di una linea, rispettivamente. Usando un ^ all'inizio della propria regex, si ottiene una reazione per cui il proprio modello (o pattern) è "ancorato" all'inizio della linea. Nell'esempio seguente, viene usata la regex ^# per riscontrare ogni linea che inizia con il carattere #:

Codice 2.7: Linee

$ grep ^# /etc/fstab
# /etc/fstab: static file system information.
#

Regex su linee intere

^ e $ possono essere combinate per indicare l'intera linea. Per esempio, la regex seguente riscontrerà una linea che inizia con il carattere # e finisce con il carattere ., qualsiasi sia il numero di altri caratteri compreso fra essi:

Codice 2.8: Indicare una linea intera

$ grep '^#.*\.$' /etc/fstab
# /etc/fstab: static file system information.

Nell'esempio precedente, l'espressione regolare è stata circondata con apici singoli per prevenire l'interpretazione del $ da parte della shell. Senza gli apici singoli, il $ sparirebbe dalla regex prima che grep possa avere la possibilità di dargli un'occhiata.

3.  FHS e la ricerca di file

Filesystem Hierarchy Standard

Il Filesystem Hierarchy Standard è un documento che specifica la disposizione delle cartelle su un sistema Linux. Il FHS fu escogitato per fornire una struttura comune così da semplificare lo sviluppo di software indipendente dalle distribuzioni -- in questo modo le cose sono di solito allo stesso posto nelle diverse distribuzioni Linux. Il FHS determina il seguente albero di cartelle (preso direttamente dalle specifiche FHS):

  • / (la cartella radice)
  • /boot (file statici del boot loader)
  • /dev (file di dispositivi, o device)
  • /etc (configurazione specifica del sistema ospite)
  • /lib (librerie condivise essenziali e moduli del kernel)
  • /mnt (punti di montaggio, o mount point, per agganciare un filesystem temporaneamente)
  • /opt (pacchetti software aggiuntivi)
  • /sbin (binari di sistema indispensabili)
  • /tmp (file temporanei)
  • /usr (gerarchia secondaria)
  • /var (dati variabili)

Le due categorie indipendenti di FHS

FHS basa la propria specifica della struttura sull'idea che ci sono due categorie indipendenti di file: condivisibili contro non condivisibili, e variabili contro statici. I dati condivisibili possono essere, appunto, condivisi tra sistemi; i dati non condivisibili sono specifici di un dato host (come i file di configurazione). I dati variabili possono essere modificati; i dati statici non sono modificabili (eccetto nelle fasi di installazione e manutenzione del sistema).

La griglia seguente riassume le quattro possibili combinazioni, con esempi di cartelle che potrebbero trovarsi in queste categorie. Ancora, questa tabella è ricavata dalla specifica di FHS (NdT: le voci della tabella sono state tradotte dalla versione originale per chiarezza e completezza):

Codice 3.1: FHS

+----------+-----------------+-------------------+
|          | condivisibili   | non condivisibili |
+----------+-----------------+-------------------+
|statiche  | /usr            | /etc              |
|          | /opt            | /boot             |
+----------+-----------------+-------------------+
|variabili | /var/mail       | /var/run          |
|          | /var/spool/news | /var/lock         |
+----------+-----------------+-------------------+

Gerarchia secondaria in /usr

Sotto /usr l'utente potrà trovare una gerarchia secondaria che assomiglia molto al filesystem principale. Non è fondamentale per /usr esistere quando la macchina si avvia, perciò può essere condiviso su una rete (condivisibile), o montato da un CD-ROM (statico). Molte configurazioni di Linux non usano condividere /usr, ma è prezioso capire l'utilità nel distinguere tra gerarchia primaria sulla cartella radice e gerarchia secondaria su /usr.

Questo è tutto ciò che verrà detto su Filesystem Hierarchy Standard. Il documento di per se è abbastanza comprensibile, quindi il lettore può andare a dargli un'occhiata. Leggendolo si avrà un'idea molto più chiara riguardo al filesystem in Linux. Lo si può trovare a http://www.pathname.com/fhs/.

Ricerca di file

I sistemi Linux spesso contengono centinaia di migliaia di file. Forse chi legge avrà abbastanza buon senso da non perdere mai traccia di nessuno di questi, ma è molto più probabile che talvolta si abbia il bisogno di trovarne qualcuno. Ci sono due diversi strumenti su Linux per la ricerca di file. Questa introduzione aiuterà il lettore a scegliere il mezzo giusto per il lavoro.

Il PATH (percorso)

Quando viene eseguito un programma da riga di comando, bash in effetti cerca attraverso una lista di cartelle per scovare il programma richiesto. Per esempio, quando si digita ls, bash non sa già che il programma ls risiede in /usr/bin. Invece, bash fa riferimento a una variabile d'ambiente chiamata PATH, che è una lista di cartelle separate da due punti. È possibile esaminare il valore di PATH:

Codice 3.2: Vedere il proprio path

$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin

Dato questo valore di PATH (il proprio può differire) bash controllerebbe prima /usr/local/bin, quindi /usr/bin in cerca del programma ls. Più probabilmente, ls sarà trovato /usr/bin, così bash potrebbe fermarsi a questo punto.

Modificare il PATH

È possibile allargare il proprio PATH assegnando ad esso su riga di comando:

Codice 3.3: Modificare il PATH

$ PATH=$PATH:~/bin
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/home/agriffis/bin

È possibile anche rimuovere elementi dal PATH, anche se questo non è così facile dato che non ci si può riferire ad un $PATH esistente. La cosa migliore è digitare semplicemente il nuovo PATH desiderato:

Codice 3.4: Rimuovere voci dal PATH

$ PATH=/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:~/bin
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/home/agriffis/bin

Per rendere le proprie modifiche al PATH disponibili ad ogni futuro processo avviato da questa shell, basta esportare le proprie modifiche usando il comando export:

Codice 3.5: Esportare il PATH (o ogni variabile, per questo scopo)

$ export PATH

Tutto ciò che c'è da sapere su "which"

È possibile controllare se è presente un dato programma nel proprio PATH usando which. Per esempio, di seguito avremo un esempio in cui in un sistema Linux non è presente il (diffuso) programma sense:

Codice 3.6: Fare richiesta per sense

$ which sense
which: no sense in (/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin)

Nell'esempio che segue, viene scovato con successo ls:

Codice 3.7: Fare richiesta per ls

$ which ls
/usr/bin/ls

"which -a"

Infine, ci si dovrebbe preoccupare del flag -a, che porta which a mostrare tutte le istanze di un dato programma presenti nel proprio PATH:

Codice 3.8: Trovare tutte le istanze di un programma presenti nel proprio PATH

$ which -a ls
/usr/bin/ls
/bin/ls

whereis

Per chi fosse interessato a ricavare più informazioni che semplicemente la locazione di un programma, dovrebbe provare il programma whereis:

Codice 3.9: Usare whereis

$ whereis ls
ls: /bin/ls /usr/bin/ls /usr/share/man/man1/ls.1.gz

Qua si vede che ls compare in due posizioni comuni per i binari, bin e /usr/bin. In aggiunta, si viene informati che c'è una pagina di manuale presente in /usr/share/man. Questa è la pagina man che dovrebbe venire mostrate digitando man ls.

Il programma whereis possiede anche l'abilità di ricercare i sorgenti, specificare percorsi di ricerca alternativi e ricercare voci non usuali. Il lettore faccia riferimento alla relativa pagina man per maggiori informazioni.

find

Il comando find è un altro pratico strumento per la propria macchina. Con find infatti non si è limitati ai programmi; è possibile ricercare ogni file desiderato, usando una varietà di criteri di ricerca. Per esempio, per cercare un file di nome README, iniziando da /usr/share/doc:

Codice 3.10: Usare find

$ find /usr/share/doc -name README
/usr/share/doc/ion-20010523/README
/usr/share/doc/bind-9.1.3-r6/dhcp-dynamic-dns-examples/README
/usr/share/doc/sane-1.0.5/README

find e wildcard

Possono essere usate wildcard "glob" nell'argomento passato a -name, a patto che vengano inserite fra apici o precedute dal carattere di escaping barra inversa (così che vengano passati a find intatti piuttosto che venire espansi da bash). Per esempio, volendo cercare file README con estensioni:

Codice 3.11: Usare find con le wildcard

$ find /usr/share/doc -name README\*
/usr/share/doc/iproute2-2.4.7/README.gz
/usr/share/doc/iproute2-2.4.7/README.iproute2+tc.gz
/usr/share/doc/iproute2-2.4.7/README.decnet.gz
/usr/share/doc/iproute2-2.4.7/examples/diffserv/README.gz
/usr/share/doc/pilot-link-0.9.6-r2/README.gz
/usr/share/doc/gnome-pilot-conduits-0.8/README.gz
/usr/share/doc/gimp-1.2.2/README.i18n.gz
/usr/share/doc/gimp-1.2.2/README.win32.gz
/usr/share/doc/gimp-1.2.2/README.gz
/usr/share/doc/gimp-1.2.2/README.perl.gz
[578 additional lines snipped]

Ignorare maiuscole/minuscole con find

Certamente, l'utente potrebbe volere ignorare la presenza di lettere maiuscole o minuscole nella propria ricerca:

Codice 3.12: Ignorare maiuscole/minuscole con find

$ find /usr/share/doc -name '[Rr][Ee][Aa][Dd][Mm][Ee]*'

O, più semplicemente:

Codice 3.13: Metodo alternativo

$ find /usr/share/doc -iname readme\*

Come si può notare, è possibile usare -iname per rendere insensibile alle maiuscole/minuscole (case-insensitive) la ricerca.

find e le espressioni regolari

Per chi ha familiarità con le espressioni regolari, c'è la possibilità di usare l'opzione -regex per limitare l'output ai nomi di file che rispettano un dato modello. In modo simile all'opzione -iname, c'è la corrispondente opzione -iregex che ignora maiuscole/minuscole nel modello. Per esempio:

Codice 3.14: Regex e find

$ find /etc -iregex '.*xt.*'
/etc/X11/xkb/types/extra
/etc/X11/xkb/semantics/xtest
/etc/X11/xkb/compat/xtest
/etc/X11/app-defaults/XTerm
/etc/X11/app-defaults/XTerm-color

Da notare che diversamente da altri programma, find impone che la regex indicata riscontri l'intero percorso, non solo una parte di esso. Per questo motivo, è necessario specificare .* a monte e a valle del modello; semplicemente usare xt come regex potrebbe non essere sufficiente.

find e tipi

L'opzione -type mette a disposizione dell'utente un modo per trovare oggetti di un certo tipo nel filesystem. I possibili argomenti per -type sono b (block device, dispositivo a blocchi), c (character device, dispositivo a caratteri), d (directory, cartella), p (named pipe, pipe dichiarata), f (regular file, file regolare), l (symbolic link, collegamento simbolico) e s (socket, punto di accesso). Per esempio, per cercare collegamenti simbolici in /usr/bin che contengono la stringa vim:

Codice 3.15: Limitare find con i tipi

$ find /usr/bin -name '*vim*' -type l
/usr/bin/rvim
/usr/bin/vimdiff
/usr/bin/gvimdiff

find e mtimes

L'opzione -mtime abilita l'utente a selezionare file basandosi sulla loro ultima nota temporale di modifica. L'argomento di mtime è dato in termini di periodi di 24 ore e molto utile quando passato in aggiunta ad un segno positivo (che significa "dopo") o un segno negativo (che significa "prima"). Per esempio, si consideri il seguente scenario:

Codice 3.16: Scenario

$ ls -l ?
-rw-------    1 root     root            0 Jan  7 18:00 a
-rw-------    1 root     root            0 Jan  6 18:00 b
-rw-------    1 root     root            0 Jan  5 18:00 c
-rw-------    1 root     root            0 Jan  4 18:00 d
$ date
Mon May  7 18:14:52 EST 2003

È possibile cercare file che sono stati creati nelle 24 ore passate:

Codice 3.17: File creati nelle 24 ore precedenti

$ find . -name \? -mtime -1
./a

Oppure l'utente potrebbe voler cercare file che sono stati creati prima dell'attuale periodo di 24 ore:

Codice 3.18: File creati prima delle ultime 24 ore

$ find . -name \? -mtime +0
./b
./c
./d

L'opzione -daystart

Se viene specificato in aggiunta l'opzione -daystart, allora i periodi temporali cominciano dall'inizio del giorno indicato piuttosto che nelle 24 ore precedenti. Per esempio, di seguito un insieme di file creati il giorno precedente e quello prima ancora:

Codice 3.19: Usare -daystart

$ find . -name \? -daystart -mtime +0 -mtime -3
./b
./c
$ ls -l b c
-rw-------    1 root     root            0 May  6 18:00 b
-rw-------    1 root     root            0 May  5 18:00 c

L'opzione -size

L'opzione -size fornisce all'utente un modo per trovare file basandosi sulla loro dimensione. In modo predefinito, l'argomento di -size è dato da blocchi di 512 byte, ma aggiungendo un suffisso possono essere rese le cose più facili. I suffissi disponibili sono b (blocchi di 512 byte), c (byte), k (kilobyte) e w (parole di 2 byte). In più, è possibile aggiungere un segno positivo ("più grande di") o negativo ("più piccolo di").

Per esempio, per cercare file regolari in /usr/bin che sono più piccoli di 50 byte:

Codice 3.20: -size in azione

$ find /usr/bin -type f -size -50c
/usr/bin/krdb
/usr/bin/run-nautilus
/usr/bin/sgmlwhich
/usr/bin/muttbug

Processare i file trovati

L'utente potrebbe chiedersi cosa sia possibile fare con tutti i file che sono stati trovati. Bene, find ha la capacità di agire sui file che sono stati trovati usando l'opzione -exec. Questa opzione accetta una riga di comando da eseguire come proprio argomento, terminata con ;, e rimpiazza ogni occorrenza di {} con il nome del file. Questo lo si capisce meglio con un esempio:

Codice 3.21: Usare -exec

$ find /usr/bin -type f -size -50c -exec ls -l '{}' ';'
-rwxr-xr-x    1 root     root           27 Oct 28 07:13 /usr/bin/krdb
-rwxr-xr-x    1 root     root           35 Nov 28 18:26 /usr/bin/run-nautilus
-rwxr-xr-x    1 root     root           25 Oct 21 17:51 /usr/bin/sgmlwhich
-rwxr-xr-x    1 root     root           26 Sep 26 08:00 /usr/bin/muttbug

Come si può vedere, find è davvero un comando potente. È cresciuto attraverso gli anni di sviluppo di UNIX e Linux. Ci sono molte altre opzioni utili in find. Si può approfondire l'argomento nella pagina di manuale di find.

locate

Sono stati discussi which, whereis e find. Il lettore potrebbe aver notato che find rischia di prendere abbastanza tempo per l'esecuzione, dato che necessita di leggere ogni cartella in cui ricerca. È dimostrato che il comando locate può rendere più veloci le cose affidandosi ad una base dati esterna generata da updatedb (che sarà discusso in seguito).

Il comando locate si affida ad ogni parte nel nome del percorso, non solo il file stesso. Per esempio:

Codice 3.22: locate in azione

$ locate bin/ls
/var/ftp/bin/ls
/bin/ls
/sbin/lsmod
/sbin/lspci
/usr/bin/lsattr
/usr/bin/lspgpot
/usr/sbin/lsof

Usare updatedb

Molti sistemi Linux hanno un "cron job" (processo cron) per aggiornare la base dati periodicamente. Se il proprio locate ritorna un errore come il seguente, allora l'utente avrà bisogno di eseguire updatedb come utente root per generare la base dati di ricerca:

Codice 3.23: Aggiornare la propria base dati per locate

$ locate bin/ls
locate: /var/spool/locate/locatedb: No such file or directory
$ su -
Password:
# updatedb

Il comando updatedb potrebbe prendere diverso tempo per l'esecuzione. Se si possiede un disco fisso rumoroso, è possibile che si sentano alcuni forti rumori mentre l'intero filesystem viene indicizzato.

mlocate

Su molte distribuzioni Linux, il comando locate è stato rimpiazzato da mlocate. C'è solitamente un collegamento simbolico a locate, così che non vi sia la necessità di ricordarsi quale si possiede. mlocate sta per "secure locate" (locate sicuro). Immagazzina informazioni sui permessi nella base dati così che ai normali utenti sia proibito curiosare in cartelle che sarebbero altrimenti non abilitati a leggere. Le informazioni sull'uso di mlocate sono essenzialmente le stesse viste per locate, anche se l'output potrebbe essere diverso in relazione all'utente che esegue il comando.

4.  Controllo dei processi

Osservare xeyes

Per imparare qualcosa sul controllo dei processi, bisogna prima avviare un processo. Assicurarsi di avere X in esecuzione e lanciare il seguente comando:

Codice 4.1: Avviare un processo

$ xeyes -center red

Il lettore noterà che una finestra di xeyes comparirà e i bulbi oculari rossi seguiranno il puntatore del mouse a giro per la finestra. Si noterà anche la non presenza di un nuovo prompt sul proprio terminale.

Fermare un processo

Per riappropriarsi del prompt, bisogna digitare Control-C (spesso indicato come Ctrl-C o ^C):

Sarà presentato un nuovo prompt di bash ma la finestra di xeyes scomparirà. Infatti, l'intero processo è stato terminato, ucciso. Piuttosto che terminarlo, lo si può solo fermare con Contrl-Z

Codice 4.2: Fermare un processo

$ xeyes -center red
Control-Z
[1]+  Stopped                 xeyes -center red
$

Questa volta è ottenuto un nuovo prompt di bash e la finestra di xeyes rimarrà attiva. Giocando un po' con questa, comunque, si noterà che le palle degli occhi sono ferme al loro posto. Se la finestra di xeyes viene coperta da un'altra finestra e quindi nuovamente scoperta, l'utente vedrà che questa non è perfino ridisegnata completamente. Il processo non sta facendo niente. In effetti è "fermato" (o "stoppato").

fg e bg

Per rendere il processo "non-stoppato" ed eseguirlo ancora, lo si può portare in primo piano (foreground) con il comando fg interno a bash:

Codice 4.3: usare fg

$ fg
(verificarlo, quindi fermare di nuovo il processo)
Control-Z
[1]+  Stopped                 xeyes -center red
$

Adesso continuiamo con esso sullo sfondo (background) con il comando bg interno a bash:

Codice 4.4: usare bg

$ bg
[1]+ xeyes -center red &
$

Ottimo. Il processo xeyes sta ora eseguendo sullo sfondo e in aggiunta è presente un nuovo prompt di bash funzionante.

Usare "&"

Nel caso in qualcuno desideri avviare xeyes sullo sfondo fin da principio (invece di usare Control-Z e bg), basterà solo aggiungere un "&" ("e" commerciale, o ampersand) alla fine della riga di comando per xeyes:

Codice 4.5: Usare un ampersand per eseguire sullo sfondo i processi

$ xeyes -center blue &
[2] 16224

Processi sullo sfondo multipli

Adesso ci sono xeyes sia rossi che blu in esecuzione sullo sfondo. Questi lavori (job) possono essere elencati con il comando jobs interno a bash:

Codice 4.6: Usare jobs

$ jobs -l
[1]- 16217 Running                 xeyes -center red &
[2]+ 16224 Running                 xeyes -center blue &

I numeri nella colonna di sinistra sono il numero di lavoro assegnato da bash quando sono stati avviati. Il secondo elemento ha un + (più) ad indicare che questo è il processo "corrente", e ciò significa che digitando fg questo verrà portato in primo piano. Esiste comunque la possibilità di scegliere un processo (o job) specifico da portare in primo piano indicando il suo numero; per esempio, fg 1 renderebbe gli xeyes rossi il processo in primo piano. La colonna che segue è l'id di processo o pid, incluso cortesemente nella lista dall'opzione -l di jobs. Infine, entrambi i processi sono "Running" (in esecuzione) e la loro riga di comando è riportata sulla destra.

Introduzione ai segnali

Per terminare, fermare o ripristinare processi, Linux usa una speciale forma di comunicazione chiamata "segnali". Inviando un certo segnale ad un processo, si può imporre ad esso di terminare, fermarsi o fare altre cose. Questo è ciò che in effetti succede digitando Control-C, Control-Z o usando i comandi interni bg o fg -- si sta usando bash per inviare un particolare segnale al processo. Questi segnali possono anche essere inviati usando il comando kill e specificando il pid (id di processo) sulla riga di comando:

Codice 4.7: Usare kill

$ kill -s SIGSTOP 16224
$ jobs -l
[1]- 16217 Running                 xeyes -center red &
[2]+ 16224 Stopped (signal)        xeyes -center blue

Come si nota, kill non "uccide" necessariamente un processo, nonostante possa farlo. Usando l'opzione "-s", kill può inviare ogni sorta di segnale ad un processo. Linux termina, ferma o ripristina i processi quando sono inviati rispettivamente i segnali SIGINT, SIGSTOP o SIGCONT. Ci sono anche altri segnali che si possono inviare ad un processo; molti di questi segnali possono essere interpretati in modo dipendente all'applicazione. È possibile sapere quali segnali un particolare processo riconosce guardando la sua pagina di manuale e cercando la sezione SIGNALS.

SIGTERM e SIGINT

In caso si desideri terminare un processo, ci sono diverse possibilità. Di base, kill invia il segnale SIGTERM, che non ha la stessa fama di SIGINT o Control-C ma di solito ottiene lo stesso risultato

Codice 4.8: Usare kill per terminare un processo

$ kill 16217
$ jobs -l
[1]- 16217 Terminated              xeyes -center red
[2]+ 16224 Stopped (signal)        xeyes -center blue

Uccidere con decisione

I processi possono ignorare sia SIGTERM che SIGINT, o per scelta o perchè sono stati fermati o in qualche modo "catatonici". In questi casi potrebbe essere necessario usare il grande martello, il segnale SIGKILL. Un processo non può ignorare SIGKILL:

Codice 4.9: Usare kill per eliminare un processo

$ kill 16224
$ jobs -l
[2]+ 16224 Stopped (signal)        xeyes -center blue
$ kill -s SIGKILL
$ jobs -l
[2]+ 16224 Interrupt               xeyes -center blue

nohup

Il terminale da cui è avviato un processo viene chiamato il terminale di controllo del processo. Alcune shell (non bash, in modo predefinito), girano un segnale SIGHUP ai processi sullo sfondo quando l'utente effettua il logout, causando la loro terminazione. Per proteggere i processi da questo comportamento, usare nohup quando viene avviato il processo:

Codice 4.10: nohup in azione

$ nohup make &
[1] 15632
$ exit

Usare ps per avere l'elenco dei processi

Il comando jobs usato in precedenza semplicemente elenca i processi che sono stati avviati dalla propria sessione di bash. Per vedere tutti i processi sul proprio sistema, usare ps con entrambe le opzioni a e x:

Codice 4.11: ps con ax

$ ps ax
  PID TTY      STAT   TIME COMMAND
    1 ?        S      0:04 init [3]
    2 ?        SW     0:11 [keventd]
    3 ?        SWN    0:13 [ksoftirqd_CPU0]
    4 ?        SW     2:33 [kswapd]
    5 ?        SW     0:00 [bdflush]

È stato riportato l'inizio dell'elenco perché è di solito una lista molto lunga. Questa da all'utente un'istantanea su cosa l'intera macchina sta facendo, ma sono una mare di informazioni da passare al setaccio. Se si escludono le opzioni ax, verranno mostrati solo i processi di cui l'utente è proprietario e che hanno un terminale di controllo. Il comando ps x mostrerà all'utente tutti i suoi processi, anche quelli senza un terminale di controllo. Usando ps a, si otterrà la lista di tutti i processi che sono attaccati ad un terminale.

Vedere la foresta e gli alberi

Possono essere ricavate anche informazioni diverse su ogni processo. L'opzione --forest rende facile analizzare la gerarchi di processi, che fornisce al lettore una indicazione su come i veri processi sul proprio sistema interagiscono tra loro. Quando un processo avvia un nuovo processo, quest'ultimo è chiamato processo "figlio" (o "child"). In un listato fornito da --forest, il processo padre (o parent) appare sulla sinistra e i figli sono mostrati come rami sulla destra:

Codice 4.12: Usare forest

$ ps x --forest
  PID TTY      STAT   TIME COMMAND
  927 pts/1    S      0:00 bash
 6690 pts/1    S      0:00  \_ bash
26909 pts/1    R      0:00      \_ ps x --forest
19930 pts/4    S      0:01 bash
25740 pts/4    S      0:04  \_ vi processes.txt

Le opzioni "u" e "l" di ps

Anche le opzioni u o l possono essere aggiunte ad ogni combinazione di a e x in modo da includere più informazioni riguardo ogni processo:

Codice 4.13: Opzione au

$ ps au
USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMAND
agriffis   403  0.0  0.0  2484   72 tty1     S     2001   0:00 -bash
chouser    404  0.0  0.0  2508   92 tty2     S     2001   0:00 -bash
root       408  0.0  0.0  1308  248 tty6     S     2001   0:00 /sbin/agetty 3
agriffis   434  0.0  0.0  1008    4 tty1     S     2001   0:00 /bin/sh /usr/X
chouser    927  0.0  0.0  2540   96 pts/1    S     2001   0:00 bash

Codice 4.14: Opzione al

$ ps al
  F   UID   PID  PPID PRI  NI   VSZ  RSS WCHAN  STAT TTY        TIME COMMAND
100  1001   403     1   9   0  2484   72 wait4  S    tty1       0:00 -bash
100  1000   404     1   9   0  2508   92 wait4  S    tty2       0:00 -bash
000     0   408     1   9   0  1308  248 read_c S    tty6       0:00 /sbin/ag
000  1001   434   403   9   0  1008    4 wait4  S    tty1       0:00 /bin/sh
000  1000   927   652   9   0  2540   96 wait4  S    pts/1      0:00 bash

Usare top

Nel caso in cui l'utente si ritrovi ad eseguire svariate volte di seguito ps, cercando di percepire i cambiamenti, probabilmente quello di cui ha bisogno è top. top mostra una lista di processi aggiornandola continuamente, insieme a alcune utili informazioni riassuntive:

Codice 4.15: top

$ top
 10:02pm  up 19 days,  6:24,  8 users,  load average: 0.04, 0.05, 0.00
75 processes: 74 sleeping, 1 running, 0 zombie, 0 stopped
CPU states:  1.3% user,  2.5% system,  0.0% nice, 96.0% idle
Mem:   256020K av,  226580K used,   29440K free,       0K shrd,    3804K buff
Swap:  136544K av,   80256K used,   56288K free                  101760K cached

  PID USER     PRI  NI  SIZE  RSS SHARE STAT  LIB %CPU %MEM   TIME COMMAND
  628 root      16   0  213M  31M  2304 S       0  1.9 12.5  91:43 X
26934 chouser   17   0  1272 1272  1076 R       0  1.1  0.4   0:00 top
  652 chouser   11   0 12016 8840  1604 S       0  0.5  3.4   3:52 gnome-termin
  641 chouser    9   0  2936 2808  1416 S       0  0.1  1.0   2:13 sawfish

nice

Ogni processo ha una priorità impostata che Linux usa per determinare come le porzioni di tempo della CPU sono condivise. È possibile assegnare la priorità ad un processo avviandolo con il comando nice:

Codice 4.16: avviare un processo con nice

$ nice -n 10 oggenc /tmp/song.wav

Dato che l'impostazione della priorità è detta nice (letteralmente "buono.gradevole"), dovrebbe essere facile ricordare che un valore più alto renderà un processo più buono nei confronti degli altri processi, permettendo ad essi di avere un accesso prioritario alla CPU. Di base, i processi sono avviati con un impostazione a 0, così l'assegnazione di un valore 10 visto sopra significa che oggenc rinuncerà puntualmente alla CPU a favore degli altri processi. Di solito, questo significa che oggenc permetterà agli altri processi di eseguire alla loro normale velocità, indipendentemente da quanto questo risulti essere avido di CPU. È possibile vedere il dato livello di bontà (livello di nice) sotto la colonna NI nei listati di ps e top presentati sopra.

renice

il comando nice può solamente cambiare la priorità di un processo quando viene avviato. Nel caso in cui si vogliano cambiare le impostazioni di priorità di un processo in esecuzione, bisogna usare renice:

Codice 4.17: usare renice

$ ps l 641
  F   UID   PID  PPID PRI  NI   VSZ  RSS WCHAN  STAT TTY        TIME COMMAND
000  1000   641     1   9   0  5876 2808 do_sel S    ?          2:14 sawfish
$ renice 10 641
641: old priority 0, new priority 10
$ ps l 641
  F   UID   PID  PPID PRI  NI   VSZ  RSS WCHAN  STAT TTY        TIME COMMAND
000  1000   641     1   9  10  5876 2808 do_sel S    ?          2:14 sawfish

5.  Elaborazione del testo

Rivisitazione della ridirezione

In precedenza all'interno di questa serie di brevi guide, è stato mostrato un esempio di come usare l'operatore > per ridirezionare l'output di un comando in un file, come segue:

Codice 5.1: Uso dell'operatore >

$ echo "firstfile" > copyme

Oltre alla ridirezione dell'output verso un file, è possibile trarre vantaggio da una potente caratteristica della shell chiamata pipe (letteralmente, "tubo"). Usando le pipe, è possibile passare l'output di un comando come input di un altro comando. Si consideri il seguente esempio:

Codice 5.2: Introduzione alle pipe

$ echo "hi there" | wc
      1       2       9

Il carattere | è usato per connettere l'output del comando sulla sinistra con l'input del comando sulla destra. Nell'esempio precedente, il comando echo stampa la stringa "hi there" seguita da un carattere di avanzamento di linea (linefeed). Il risultato apparirebbe di norma sul terminale ma la pipe lo ridireziona verso il comando wc, che mostra a video il numero di linee, parole e caratteri nel proprio input.

Un esempio di uso delle pipe

Di seguito un altro semplice esempio:

Codice 5.3: pipe in azione

$ ls -s | sort -n

In questo caso, ls -l mostrerebbe normalmente una lista della cartella corrente a terminale, precedendo ogni file con la sua dimensione. Invece è stato ridirezionato il suo output verso sort -n, che ordina numericamente il risultato. Questo è davvero un modo molto utile per trovare grossi file nella propria cartella home.

Gli esempi che seguono sono un po' più complessi ma dimostrano la potenza che può essere concentrata nell'uso delle pipe. Saranno usati comandi non ancora discussi, ma il lettore non deve lasciarsi scoraggiare. Bisogna invece concentrarsi nella comprensione sul come le pipe operano così da poterle impiegare nell'uso di tutti i giorni del proprio sistema Linux.

La pipeline di decompressione

Di solito per decomprimere e spacchettare un archivio tar compresso, bisogna agire come segue:

Codice 5.4: Spacchettare un file

$ bzip2 -d linux-2.4.16.tar.bz2
$ tar xvf linux-2.4.16.tar

Il rovescio della medaglia in questo metodo è dato dal fatto che viene richiesta la creazione di un file intermedio decompresso sul proprio disco. Dato che tar ha la capacità di leggere direttamente dal proprio input (invece che da uno specifico file), potrebbe essere ottenuto lo stesso risultato finale usando una pipeline (cioè una riga di comando che vede presente una o più pipe):

Codice 5.5: spacchettare usando una pipeline

$ bzip2 -dc linux-2.4.16.tar.bz2 | tar xvf -

Non male. L'immagine compressa è stata estratta senza la necessità di un file intermedio.

Una pipeline più lunga

Ecco un altro esempio di pipeline:

Codice 5.6: pipeline più lunghe

$ cat mio_file.txt | sort | uniq | wc -l

È stato usato cat per fornire il contenuto di mio_file.txt al comando sort. Quando il comando sort riceve dati in ingresso, ordina tutte le linee ricevute così che risultino essere in ordine alfabetico e poi invia il risultato a uniq. uniq rimuove ogni linea duplicata (e richiede che il proprio input sia ordinato, tra l'altro) inviando l'output ripulito a wc -l. Il comando wc è stato già visto in precedenza ma senza opzioni a riga di comando. Quando viene passata l'opzione -l, viene stampato il solo numero di linee in ingresso, piuttosto che includere anche parole e caratteri. Si può notare che questa pipeline restituirà il numero di linee uniche (non identiche) presenti in un file di testo.

Il lettore è invitato a creare un paio di file di testo con il proprio editor preferito e usare questa pipeline per osservarne i risultati forniti.

Cominciare l'avventura dell'elaborazione del testo

Adesso sarà dato il via ad una gita fra i comandi di base per l'elaborazione del testo. Poiché verrà coperto molto materiale in questa breve guida, non rimane lo spazio per fornire esempi per ogni comando. Piuttosto, il lettore è incoraggiato a leggere la pagina di manuale di ogni comando (digitando man echo, per esempio) e apprendere come ogni comando lavora anche in congiunzione con le proprie opzioni, spendendo un po' di tempo nel fare tentativi con ognuno di essi. Come regola, questi comandi stampano il risultato di ogni operazione di elaborazione del testo sul terminale piuttosto che modificare uno specifico file. Dopo aver raggiunto la fine del nostro giro panoramico fra i comandi di base in Linux per l'elaborazione del testo, verrà data un'occhiata più da vicino alla ridirezione dei dati in ingresso e uscita. Quindi non ci si preoccupi, c'è luce alla fine del tunnel.

echo stampa il proprio argomento sul terminale. Usare l'opzione -e se si desidera inserire sequenze di caratteri speciali nell'argomento; per esempio echo -e "foo\nfoo" stamperà foo, quindi un carattere di nuova linea e poi ancora foo. Usare l'opzione -n per indicare ad echo di omettere il carattere di nuova linea al termine che viene aggiunto ai dati in uscita in modo predefinito.

cat stamperà i contenuti dei file specificati come argomenti sul terminale. Pratico come primo comando di una pipeline, per esempio, cat foo.txt | blah.

sort stamperà i contenuti di un file specificato sulla riga di comando in ordine alfabetico. Ovviamente, sort accetta anche dati in ingresso provenienti di pipe. Digitare man sort per familiarizzare con le sue varie opzioni che controllano il comportamento durante l'ordinamento.

uniq prende un file o un flusso dati (attraverso una pipe) già ordinato e rimuove le linee duplicate.

wc stampa a video il numero di linee, parole e byte in uno specifico file o nel flusso di dati in ingresso (da una pipeline). Digitare man wc per imparare come mettere a punto quali conteggi sono mostrati.

head stampa a video le prime dieci linee di un file o flusso dati. Usare l'opzione -n per specificare quante linee dovrebbero essere visualizzate.

tail stampa a video le ultime dieci linee di un file o flusso dati. Usare l'opzione -n per specificare quante linee dovrebbero essere mostrate.

tac è simile a cat, ma stampa a video tutte le linee in ordine inverso; in altre parole, l'ultima linea è mostrata per prima.

expand converte i valori di tab ("\t") in ingresso in spazi. Usare l'opzione -t per specificare il numero a cui fermarsi.

unexpand converte gli spazi in ingresso in valori di tab. Usare l'opzione -t per specificare il numero a cui fermarsi.

cut è usato per estrarre campi delimitati da caratteri da ogni linea di un file o flusso dati in ingresso.

Il comando nl aggiunge un numero di riga ad ogni linea in ingresso. Utile per la stampa a video.

pr è usato per dividere i file in pagine multiple in uscita; tipicamente viene usato per la stampa.

tr è uno strumento di traduzione di caratteri; è usato per mappare certi caratteri nel flusso in ingresso su determinati caratteri nel flusso di uscita.

sed è un potente editor di testo orientato ai flussi. È possibile imparare molto di più su sed negli articoli seguenti su developerWorks di IBM:

Se si sta progettando di sostenere gli esami del LPI, assicurarsi di leggere i primi due articoli di questa serie.

awk è un utile linguaggio per l'elaborazione del testo orientato alle linee. Per imparare di più su awk, leggere i seguenti articoli da developerWorks di IBM:

od è progettato per trasformare il flusso in ingresso in un formato "dump" ottale o esadecimale.

split è un comando usato per dividere un grosso file in molti di dimensioni minori, così da avere porzioni più maneggiabili.

fmt riformatterà i paragrafi così da ristabilire le misure sui margini. In questo periodo è meno utile data che questa caratteristica è già presente all'interno di molti editor di testo ma è ancora una buona cosa da conoscere.

paste prende due o più file come ingresso, concatena ogni linea in sequenza presa dai file di ingresso e rende in uscita le linee risultanti. Può essere utile per creare tabelle o colonne di testo.

join è simile a paste ma usa un campo (di base, il primo) in ogni linea di ingresso per riscontrare cosa dovrebbe essere combinato su una singola linea.

tee stampa il proprio ingresso sia su un file che a video. È utile quando si voglia creare un log (traccia) di qualcosa ma lo si voglia anche poter vedere a schermo.

Senza sosta, la ridirezione

In modo simile all'uso di > da riga di comando in bash, è possibile sfruttare < per ridirezionare un file verso un comando. Per molti comandi, l'utente può semplicemente specificare il nome del file da riga di comando, in ogni caso altri lavorano solo sullo standard input.

Bash e altre shell supportano il concetto di "herefile" (letteralmente, "file in questa posizione"). Questo permette di indicare l'input per un dato comando sulla riga di seguito all'invocazione del comando stesso, terminando con un valore di sentinella. Tutto ciò è mostrato in modo semplice attraverso un esempio:

Codice 5.7: Redirezione in azione

$ sort <<END
mela
mirtillo
banana
END
mela
banana
mirtillo

Nell'esempio sopra, vengono digitate le parole mela, mirtillo e banana, seguite da "END" per indicare la fine dei dati in ingresso. Il programma sort quindi restituisce le nostre parole in ordine alfabetico.

Usare >>

Ci si potrebbe aspettare che l'espressione >> faccia qualcosa di analogo a <<, ma non è così. Semplicemente comporta l'aggiunta dei dati in uscita ad un file, piuttosto che sovrascrivere come farebbe > Per esempio:

Codice 5.8: Redirezionare verso un file

$ echo Ciao > mio_file
$ echo a voi. > mio_file
$ cat mio_file
a voi.

Imprevisto. È stata persa la porzione "Ciao". Quello che si voleva fare è questo:

Codice 5.9: Aggiungere ad un file

$ echo Ciao > mio_file
$ echo a voi. >> mio_file
$ cat mio_file
Ciao
a voi.

Molto meglio.

6.  Moduli del Kernel

Conoscere "uname"

Il comando uname fornisce una varietà di interessanti informazioni riguardo il proprio sistema. Si riporta ciò che viene mostrato sul sistema di sviluppo dell'Autore quando viene digitato uname -a, che richiede al comando uname di stampare tutte le proprie informazioni di seguito:

Codice 6.1: uname -a

$ uname -a
Linux inventor 2.4.20-gaming-r1 #1 Fri Apr 11 18:33:35 MDT 2003 i686 AMD Athlon(tm) XP 2100+ AuthenticAMD GNU/Linux

Altre follie con uname

Adesso, bisogna dare un'occhiata alle informazioni che uname fornisce:

Codice 6.2: Informazioni fornite da uname

info. option                    arg     example
kernel name                     -s      "Linux"
hostname                        -n      "inventor"
kernel release                  -r      "2.4.20-gaming-r1"
kernel version                  -v      "#1 Fri Apr 11 18:33:35 MDT 2003"
machine                         -m      "i686"
processor                       -p      "AMD Athlon(tm) XP 2100+"
hardware platform               -i      "AuthenticAMD"
operating system                -o      "GNU/Linux"

Interessante. E cosa stampa invece il comando uname -a del lettore?

La release (rilascio) del kernel

Ecco un trucco magico. Primo, digitare uname -r per fare in modo che il comando uname stampi la release del kernel Linux attualmente in esecuzione.

Adesso, bisogna dare un'occhiata alla cartella /lib/modules e --velocemente-- si potrebbe scommettere sul fatto che è stata trovata una cartella con lo stesso nome preciso. Certo, non è cosa così magica ma questo potrebbe essere un buon momento per discutere riguardo al significato delle cartelle in /lib/modules e spiegare cosa sono i moduli del kernel.

Il kernel

Il kernel Linux è il cuore di ciò che viene comunemente indicato come "Linux" -- questo è il pezzo di codice che accede al proprio hardware direttamente e fornisce astrazioni in modo che vecchi programmi regolari possano essere eseguiti. Grazie al kernel, il proprio editor di testi non necessita di preoccuparsi quando sta scrivendo su un disco SCSI o IDE -- o perfino su un disco in RAM. Scrive semplicemente su un filesystem e il kernel si prende cura del resto.

Introduzione ai moduli del kernel

Quindi, cosa sono i moduli del kernel? Bene, sono parti del kernel che sono state immagazzinate in uno speciale formato su disco. In base ai comandi dell'utente, possono essere caricati nel kernel in esecuzione per mettere a disposizione funzionalità aggiuntive.

Poichè i moduli del kernel sono caricati su richiesta, è possibile che il proprio kernel supporti molte funzionalità aggiuntive che l'utente potrebbe non volere abilitate di solito. Ma di tanto in tanto, questi moduli del kernel hanno il vizio di diventare abbastanza utili a possono essere caricati -- spesso automaticamente -- per supportare questi strani filesystem o dispositivi hardware usati raramente.

Moduli del Kernel in poche parole

In breve, i moduli del kernel permettono al kernel in esecuzione di abilitare potenzialità su base on-demand (a richiesta). Senza i moduli del kernel, bisognerebbe compilare un nuovo kernel per intero e riavviare in modo da permettergli di supportare qualcosa di nuovo.

lsmod

Per scoprire quali moduli sono caricati al momento sul proprio sistema, usare il comando lsmod:

Codice 6.3: usare lsmod

# lsmod
Module                  Size  Used by    Tainted: PF
vmnet                  20520   5
vmmon                  22484  11
nvidia               1547648  10
mousedev                3860   2
hid                    16772   0  (unused)
usbmouse                1848   0  (unused)
input                   3136   0  [mousedev hid usbmouse]
usb-ohci               15976   0  (unused)
ehci-hcd               13288   0  (unused)
emu10k1                64264   2
ac97_codec              9000   0  [emu10k1]
sound                  51508   0  [emu10k1]
usbcore                55168   1  [hid usbmouse usb-ohci ehci-hcd]

Elenco dei moduli

Come si può notare, sul sistema dell'Autore ci sono ben pochi moduli caricati. I moduli vmnet e vmmon mettono a disposizione funzionalità necessarie per il programma VMWare, che permette di eseguire un PC virtuale in una finestra sul desktop. Il modulo "nvidia" proviene dall'ente NVIDIA e permette di usare la scheda grafica accelerata 3D ad alte prestazioni sotto Linux pur godendo dei vantaggi delle sue discrete caratteristiche.

Di seguito è presente un gruppo di moduli che sono usati per mettere a disposizione il supporto per dispositivi d'ingresso basati su USB -- chiamati "mousedev", "input", "usb-ohci", "ehci-hcd" e "usbcore". Ha spesso senso configurare il proprio kernel così da fornire il supporto USB sotto forma di modulo. Il perché è dato dal fatto che i dispositivi USB sono di tipo "plug and play" (letteralmente, inserisci e usa) e quando l'utente ha il proprio supporto USB come modulo può allora uscire di casa e comprare un nuovo dispositivo USB, inserirlo nel proprio sistema e scoprire che il sistema automaticamente carica i moduli appropriati per abilitare questo servizio. È una via comoda per fare le cose.

Moduli di terze parti

Esplorando la lista dei moduli dell'Autore si notano "emu10k1", "ac97_codec", e "sound" i quali tutti insieme forniscono il supporto per la scheda audio SoundBlaster Audigy.

Il lettore attento avrà notato che molti dei moduli del kernel provengono dai sorgenti del kernel stesso. Per esempio, tutti i moduli relativi a USB sono compilati a partire dai sorgenti standard del Kernel Linux. Comunque, i moduli relativi a nvidia, emu10k1 e VMWare provengono da altri sorgenti. Questo mette in risalto un altro grande vantaggio dei moduli del kernel -- permettono a terze parti di fornire funzionalità del kernel molto richieste e mettono a disposizione queste funzionalità semplicemente tramite il "plug in" (caricamento) all'interno di un kernel Linux in esecuzione. Nessun riavvio è necessario.

depmod e compagnia

Nella cartella /lib/modules/2.4.20-gaming-r1/ dell'Autore, sono presenti un certo numero di file che cominciano con la stringa "modules.":

Codice 6.4: altri moduli

$ ls /lib/modules/2.4.20-gaming-r1/modules.*
/lib/modules/2.4.20-gaming-r1/modules.dep
/lib/modules/2.4.20-gaming-r1/modules.generic_string
/lib/modules/2.4.20-gaming-r1/modules.ieee1394map
/lib/modules/2.4.20-gaming-r1/modules.isapnpmap
/lib/modules/2.4.20-gaming-r1/modules.parportmap
/lib/modules/2.4.20-gaming-r1/modules.pcimap
/lib/modules/2.4.20-gaming-r1/modules.pnpbiosmap
/lib/modules/2.4.20-gaming-r1/modules.usbmap

Questi file contengono diverse informazioni sulle dipendenze. Per esempio, registrano informazioni sulle *dipendenze* per i moduli -- alcuni moduli richiedono che altri moduli vengano caricati prima di essere eseguiti. Questa informazioni è memorizzata in questi file.

Come prendere i moduli

Molti moduli del kernel sono progettati per lavorare con dispositivi hardware specifici, come il modulo "emu10k1" che è relativo alla scheda SounBlaster Audigy. Per questo tipo di moduli, questi file riportano anche gli ID PCI e marcatori di identificazione simili per i dispositivi hardware che supportano. Questa informazione può essere usata da strumenti come gli script di "hotplug" (che verranno discussi in una breve guida in seguito) per auto-rilevare l'hardware e caricare il modulo appropriato per supportare il detto hardware automaticamente.

Usare depmod

Se non si installa mai un nuovo modulo, queste informazioni sulle dipendenze potrebbero diventare obsolete. Per aggiornarle, semplicemente digitare depmode -a. Il programma depmod effettuerà una scansione di tutti i moduli nelle proprie cartelle presenti in /lib/modules aggiornando le informazioni sulle dipendenze. Questo è possibile effettuando una scansione dei file di modulo in /lib/modules e cercando all'interno dei moduli ciò che viene chiamato "symbols".

Individuare i moduli del kernel

Quindi, vediamo a cosa assomigliano i moduli del kernel. Per i kernel 2.4, sono di solito ogni file che termina con ".o" presente nell'albero /lib/modules>. Per vedere tutti i moduli in /lib/modules, digitare quanto segue:

Codice 6.5: moduli del kernel in /lib/modules

# find /lib/modules -name '*.o'
/lib/modules/2.4.20-gaming-r1/misc/vmmon.o
/lib/modules/2.4.20-gaming-r1/misc/vmnet.o
/lib/modules/2.4.20-gaming-r1/video/nvidia.o
/lib/modules/2.4.20-gaming-r1/kernel/fs/fat/fat.o
/lib/modules/2.4.20-gaming-r1/kernel/fs/vfat/vfat.o
/lib/modules/2.4.20-gaming-r1/kernel/fs/minix/minix.o
[elenco "troncato" per brevità]

insmod contro modprobe

Ora, vediamo come chiunque può caricare un modulo all'interno di un kernel in esecuzione. Un modo è usare il comando insmod e specificare il percorso completo del modulo che si desidera caricare:

Codice 6.6: usare insmod

# insmod /lib/modules/2.4.20-gaming-r1/kernel/fs/fat/fat.o
# lsmod | grep fat
fat                    29272   0  (unused)

Comunque, chiunque normalmente carica moduli usando il comando modprobe. Una delle cose buone del comando modprobe è che questo automaticamente si preoccupa di caricare ogni modulo di dipendenza. Inoltre, non c'è bisogno di specificare il percorso per il modulo che si desidera caricare e neanche indicare il ".o" finale.

rmmod e modprobe in azione

Adesso provare a rimuovere il proprio modulo "fat.o" e caricarlo usando modprobe:

Codice 6.7: rmmod e modprobe in azione

# rmmod fat
# lsmod | grep fat
# modprobe fat
# lsmod | grep fat
fat                    29272   0  (unused)

Come si può vedere, il comando rmmod opera in modo simile a modprobe, ma ha l'effetto opposto -- rimuove il modulo specificato.

Farsi amici modinfo e modules.conf

È possibile usare il comando modinfo per imparare cose interessanti sui propri moduli preferiti:

Codice 6.8: Usare modinfo

# modinfo fat
filename:    /lib/modules/2.4.20-gaming-r1/kernel/fs/fat/fat.o
description: <none>
author:      <none>
license:     "GPL"

Aggiungiamo una nota speciale sul file /etc/modules.conf. Questo file contiene informazioni di configurazione per modprobe. Permette all'utente di mettere a punto le funzionalità di modprobe dicendogli di caricare i moduli prima/dopo il caricamento di altri, eseguire script prima/dopo il caricamento di moduli e via dicendo.

Suggerimenti per modules.conf

La sintassi e funzionalità di modules.conf è abbastanza complicata e questa guida non scenderà ora nello specifico (digitare man modules.conf per tutti i dettagli più sanguinosi), ma di seguito sono riportate alcune cose che il lettore *dovrebbe* conoscere riguardo a questo file.

Primo, molte distribuzioni generano questo file automaticamente da un gruppo di file in un'altra cartella, come /etc/modules.d/. Per esempio, Gentoo Linux ha una cartella /etc/modules.d/ e lanciando il comando update-modules recupererà ogni file in /etc/modules.d/ e li concatenerà per produrre un nuovo /etc/modules.conf. Quindi, bisogna effettuare i proprio cambiamenti ai file in /etc/modules.d/ ed eseguire update-modules se si sta usando Gentoo. Se si sta usando Debian, la procedura è simile eccetto che la cartella è chiamata /etc/modutils/.

7.  Riassunto e Risorse

Riassunto

Congratulazioni; è stata raggiunta la fine di questa breve guida sulle basi dell'amministrazione in Linux. L'Autore spera di avere aiutato il lettore a solidificare la propria conoscenza di base su Linux. Prega inoltre di partecipare alla prossima breve guida che coprirà l'amministrazione intermedia, dove verrà costruito sulle fondamenta disposte adesso, coprendo argomenti come i permessi in Linux e il modello di proprietà, la gestione degli account utente, la creazione di filesystem e il loro montaggio e così via. Si ricordi, continuando in questa serie di brevi guide, a breve il lettore sarà pronto a raggiungere la propria Certificazione LPIC di Livello 1 del Linux Professional Institute.

Risorse

Parlando della Certificazione LPIC, se questo è ciò a cui il lettore è interessato, si raccomanda di studiare le seguenti risorse, le quali sono state attentamente selezionate per incrementare il materiale coperto in questa breve guida:

Ci sono un numero di buone risorse sulle espressioni regolari in rete. Di seguito alcune scovate dall'Autore:

Assicurarsi di documentarsi su Filesystem Hierarchy Standard all'indirizzo http://www.pathname.com/fhs/.

Nella serie di articoli Bash tramite esempi, l'autore mostra come usare i construtti di programmazione bash per scrivere i propri script bash. Questa serie (in particolare parti uno e due) saranno una buona preparazione per l'esame LPIC di Livello 1:

È possibile imparare di più su sed negli articoli rilevanti su developerWorks di IBM. Se si sta pianificando di sostenere l'esame LPI, assicurarsi di leggere i primi due articoli di questa serie.

Per imparare di più su awk, leggere gli articoli rilevanti su developerWorks di IBM.

È caldamente raccomandato il documento Technical FAQ for Linux users (FAQ tecniche per utenti Linux), una lista approfondita di 50 pagine su domande poste di frequente riguardo a Linux, seguite da dettagliate risposte. Le FAQ stesse sono in formato PDF (Acrobat). Se il lettore è un utente Linux principiante o intermedio, dovrebbe veramente imporre a sè stesso di dare un'occhiata alle FAQ.

Se non si è molto familiari con l'editor vi, è fortemente raccomandato di esaminare la guida scritta dall'Autore e intitolata Vi -- the cheat sheet method (Vi -- bignami). Questa breve guida fornisce al lettore una leggera ma veloce introduzione a questo potente editor di testi. Bisogna considerare questo materiale come obbligatorio se non si sa come usare vi.



Stampa

Aggiornato il 14 novembre 2010

Oggetto: In questa breve guida, il lettore imparerà come usare le espressioni regolari nella la ricerca di file per modelli di testo, come individuare file nel proprio sistema e come avere pieno controllo dei processi in Linux. Sarà data perfino una veloce introduzione alle pipeline della shell, la ridirezione e i comandi per l'elaborazione del testo. Alla fine di questa breve guida, il lettore avrà solide fondamente sulle basi dell'amministrazione in Linux e sarà pronto per iniziare ad imparare tecniche di amministrazione di sistemi Linux più avanzate nella guida che seguirà.

Daniel Robbins
Autore

Chris Houser
Autore

Aron Griffis
Autore

Michele Caini
Traduzione

Donate to support our development efforts.

Copyright 2001-2014 Gentoo Foundation, Inc. Questions, Comments? Contact us.