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
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
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.
|