Crea sito
28 Ottobre 2020

Officine Informatiche Roma

ICT SERVICES ROMA – BAZAAR INFORMATICO

LINUX COMMAND LINE: 6- REINDIRIZZAMENTO

14 min read
In questa lezione sveleremo quale potrebbe essere la caratteristica più interessante della riga di comando. Si chiama reindirizzamento I / O. "I / O" sta per input / output e con questa funzione è possibile reindirizzare l'input e l'output dei comandi da e verso i file, nonché collegare più comandi insieme in potenti pipeline di comandi.

In questa lezione sveleremo quale potrebbe essere la caratteristica più interessante della riga di comando.

Si chiama reindirizzamento I / O.

“I / O” sta per input / output e con questa funzione è possibile reindirizzare l’input e l’output dei comandi da e verso i file, nonché collegare più comandi insieme in potenti pipeline di comandi.

Per mostrare questa funzione, introdurremo i seguenti comandi:

cat                                Concatena i file
ordina                        Ordina le righe di testo
uniq                            Segnala o omette le righe ripetute
grep                            Stampa le linee corrispondenti a un motivo
wc                                Stampa i conteggi di nuova riga, parola e byte per ciascun file
head                           Emette la prima parte di un file
tail                               Emette l’ultima parte di un file
tee                               Leggi dallo standard input e scrivi nello standard output e file

Standard Input, Output, and Error

Molti dei programmi che abbiamo usato finora producono output di qualche tipo. Questo output è spesso costituito da due tipi.

• I risultati del programma; cioè, i dati per cui è progettato il programma
produrre
• Messaggi di stato e di errore che indicano come procede il programma

Se osserviamo un comando come ls, possiamo vedere che mostra i suoi risultati e i suoi messaggi di errore sullo schermo. Seguendo il tema Unix di “tutto è un file”, programmi del genere poiché in realtà inviano i loro risultati a un file speciale chiamato output standard (spesso espresso come stdout) e i loro messaggi di stato a un altro file chiamato errore standard (stderr). Per impostazione predefinita, sia l’output standard che l’errore standard sono collegati allo schermo e non salvati in un file su disco. Inoltre, molti programmi prendono input da una struttura chiamata standard input (stdin), che è, di default, attaccato alla tastiera. Il reindirizzamento I / O ci consente di cambiare la destinazione dell’output e la provenienza dell’input. Normalmente, l’output arriva allo schermo e l’input viene dalla tastiera, ma con il reindirizzamento I / O, possiamo cambiarlo.

Reindirizzamento dell’output standard
Il reindirizzamento I / O ci consente di ridefinire la destinazione dell’output standard. Per reindirizzare l’output standard su un altro file anziché sullo schermo, utilizziamo l’operatore> reindirizzamento seguito dal nome del file. Perché dovremmo voler fare questo? È spesso utile memorizzare l’output di un comando in un file. Ad esempio, potremmo dire alla shell di inviare l’output del comando ls al file ls-output.txt anziché allo schermo.

[[email protected] ~]$ ls -l /usr/bin > ls-output.txt

Qui, abbiamo creato un lungo elenco della directory / usr / bin e inviato i risultati al file ls-output.txt. Esaminiamo l’output reindirizzato del comando, mostrato qui:

[[email protected] ~]$ ls -l ls-output.txt
-rw-rw-r– 1 me me 167878 2018-02-01 15:07 ls-output.txt

Bene: un file di testo bello, grande.
Se guardiamo il file con meno, vedremo che il file ls-output.txt contiene effettivamente i risultati del nostro comando ls.

[[email protected] ~]$ less ls-output.txt

Ora, ripetiamo il nostro test di reindirizzamento, ma questa volta con una svolta.
Modificheremo il nome della directory in uno che non esiste.

[[email protected] ~]$ ls -l /bin/usr > ls-output.txt
ls: cannot access /bin/usr: No such file or directory

Abbiamo ricevuto un messaggio di errore. Questo ha senso poiché abbiamo specificato la directory / bin / usr inesistente, ma perché il messaggio di errore è stato visualizzato sullo schermo anziché essere reindirizzato al file ls output.txt? La risposta è che il programma ls non invia i suoi messaggi di errore all’output standard. Invece, come la maggior parte dei programmi Unix ben scritti, invia i suoi messaggi di errore a errori standard. Poiché abbiamo reindirizzato solo l’output standard e non l’errore standard, il messaggio di errore veniva comunque inviato allo schermo. Vedremo come reindirizzare l’errore standard in un minuto, ma prima diamo un’occhiata a cosa è successo al nostro file di output.

[[email protected] ~]$ ls -l ls-output.txt
-rw-rw-r– 1 me me 0 2018-02-01 15:08 ls-output.txt

Il file ora ha lunghezza zero! Questo perché quando reindirizziamo l’output con l’operatore> reindirizzamento, il file di destinazione viene sempre riscritto dall’inizio. Poiché il nostro comando ls non ha generato risultati e solo un messaggio di errore, l’operazione di reindirizzamento ha iniziato a riscrivere il file e quindi si è interrotta a causa dell’errore, determinando il suo troncamento. In effetti, se mai dovessimo effettivamente troncare un file (o creare un nuovo file vuoto), possiamo usare un trucco come questo:

[[email protected] ~]$ > ls-output.txt

Semplicemente usando l’operatore di reindirizzamento senza un comando che precede, troncherà un file esistente o creerà un nuovo file vuoto. Quindi, come possiamo aggiungere l’output reindirizzato a un file invece di sovrascrivere il file dall’inizio? Per questo, usiamo l’operatore >> reindirizzamento, in questo modo:

[[email protected] ~]$ ls -l /usr/bin >> ls-output.txt

L’uso dell’operatore >> comporterà l’aggiunta dell’output al file. Se il file non esiste già, viene creato come se fosse stato utilizzato l’operatore>. Mettiamolo alla prova.

[[email protected] ~]$ ls -l /usr/bin >> ls-output.txt
[[email protected] ~]$ ls -l /usr/bin >> ls-output.txt
[[email protected] ~]$ ls -l /usr/bin >> ls-output.txt
[[email protected] ~]$ ls -l ls-output.txt
-rw-rw-r– 1 me me 503634 2018-02-01 15:45 ls-output.txt

Abbiamo ripetuto il comando tre volte, ottenendo un file di output tre volte più grande.

Reindirizzamento dell’errore standard
Il reindirizzamento dell’errore standard manca della facilità di un operatore di reindirizzamento dedicato. Per reindirizzare l’errore standard, dobbiamo fare riferimento al suo descrittore di file. Un programma può produrre output su uno dei numerosi flussi di file numerati. Mentre abbiamo fatto riferimento ai primi tre di questi flussi di file come input, output ed errori standard, la shell li fa riferimento internamente come descrittori di file 0, 1 e 2, rispettivamente. La shell fornisce una notazione per reindirizzare i file usando il numero del descrittore di file. Perché l’errore standard è lo stesso del descrittore di file
numero 2, possiamo reindirizzare l’errore standard con questa notazione:

[me @ linuxbox ~] $ ls -l / bin / usr 2> ls-error.txt

Il descrittore di file 2 viene posizionato immediatamente prima dell’operatore di reindirizzamento per eseguire il reindirizzamento dell’errore standard sul file ls-error.txt.

Reindirizzamento dell’output standard e dell’errore standard su un file

Ci sono casi in cui potremmo voler catturare tutto l’output di un comando in un singolo file.
Per fare ciò, dobbiamo reindirizzare contemporaneamente sia l’output standard sia l’errore standard.
Ci sono due modi per farlo.
Qui è mostrato il modo tradizionale, che funziona con le vecchie versioni della shell:

[me @ linuxbox ~] $ ls -l / bin / usr> ls-output.txt 2> & 1

Usando questo metodo, eseguiamo due reindirizzamenti.
Prima reindirizziamo l’output standard sul file ls-output.txt, quindi reindirizziamo il descrittore di file 2 (errore standard) al descrittore di file 1 (output standard) usando la notazione 2> & 1.

Si noti che l’ordine dei reindirizzamenti è significativo

Il reindirizzamento dell’errore standard deve sempre verificarsi dopo il reindirizzamento dell’output standard o non funziona. L’esempio seguente reindirizza l’errore standard al file ls-output.txt:
> ls-output.txt 2> & 1
Se l’ordine viene modificato come segue, l’errore standard viene indirizzato alla schermata:
2> & 1> ls-output.txt

Le versioni recenti di bash forniscono un secondo metodo più snello per eseguire questo reindirizzamento combinato, mostrato qui:
[me @ linuxbox ~] $ ls -l / bin / usr &> ls-output.txt

In questo esempio, utilizziamo la notazione singola &> per reindirizzare l’output standard e l’errore standard sul file ls-output.txt.
È inoltre possibile aggiungere l’output standard e i flussi di errore standard a un singolo file in questo modo:
[me @ linuxbox ~] $ ls -l / bin / usr & >> ls-output.txt

Smaltimento di output indesiderato

A volte “il silenzio è d’oro” e non vogliamo output da un comando; vogliamo solo buttarlo via.
Ciò vale in particolare per i messaggi di errore e di stato. Il sistema fornisce un modo per farlo reindirizzando l’output su un file speciale chiamato
/ dev / null.

Questo file è un dispositivo di sistema spesso definito bit bucket, che accetta input e non fa nulla con esso.
Per eliminare i messaggi di errore da un comando, eseguiamo questa operazione:

[me @ linuxbox ~] $ ls -l / bin / usr 2> / dev / null

/ dev / null nella cultura Unix

Il “bit bucket” è un antico concetto di Unix e, a causa della sua universalità, è apparso in molte parti della cultura di Unix.

Quando qualcuno dice che stanno inviando i tuoi commenti a / dev / null, ora sai cosa significa.
Nei sistemi operativi Unix e Unix-like, /dev/null (null device, dispositivo nullo) è un file virtuale (ossia non fisicamente presente su memoria di massa) con la caratteristica di scartare (non memorizzare) tutti i dati che gli vengono scritti.
È sempre possibile effettuarvi scritture di quantità arbitrarie di dati, mentre in lettura non viene mai restituito alcun dato. In gergo è spesso chiamato buco nero o cestino per bit (da bit bucket).

Reindirizzamento dell’input standard
Fino ad ora, non abbiamo riscontrato alcun comando che utilizzi l’input standard (in realtà ce l’abbiamo, ma riveleremo quella sorpresa un po ‘più tardi), quindi dobbiamo introdurne uno. cat: file concatenati
Il comando cat legge uno o più file e li copia nell’output standard in questo modo:
cat nome file
Nella maggior parte dei casi, puoi pensare a cat come analogo al comando TYPE in DOS. Puoi usarlo per visualizzare i file senza il paging.
Ad esempio, di seguito verranno visualizzati i contenuti del file ls-output.txt:
[me @ linuxbox ~] $ cat ls-output.txt
cat viene spesso utilizzato per visualizzare brevi file di testo.
Poiché cat può accettare più di un file come argomento, può anche essere utilizzato per unire i file.

Supponiamo di aver scaricato un file di grandi dimensioni che è stato suddiviso in più parti (i file multimediali sono spesso divisi in questo modo su Usenet) e che vogliamo unirli nuovamente insieme. Se i file sono stati denominati come segue:

movie.mpeg.001 movie.mpeg.002 … movie.mpeg.099
potremmo unirli di nuovo insieme a questo comando:
cat movie.mpeg.0 *> movie.mpeg

Poiché i caratteri jolly si espandono sempre in ordine ordinato, gli argomenti verranno disposti nell’ordine corretto.
Va tutto bene, ma cosa c’entra questo con l’input standard?

Ancora niente, ma proviamo qualcos’altro.

Cosa succede se entriamo in cat senza argomenti?
[me @ linuxbox ~] $ cat

Non succede nulla; si trova lì come se fosse appeso. Potrebbe sembrare così, ma sta davvero facendo esattamente quello che dovrebbe fare.
Se a cat non viene dato alcun argomento, si legge dall’input standard e poiché l’input standard è, per impostazione predefinita, collegato alla tastiera, sta aspettando che digitiamo qualcosa!

Prova ad aggiungere il testo seguente e premi Invio:
[me @ linuxbox ~] $ cat
La volpe marrone veloce saltò sul cane pigro.
Quindi, digita ctrl-D (ovvero, tieni premuto il tasto ctrl e premi D) per dire a cat che ha raggiunto la fine del file (EOF) sull’input standard.
[me @ linuxbox ~] $ cat
La volpe marrone veloce saltò sul cane pigro.
La volpe marrone veloce saltò sul cane pigro.

In assenza di argomenti sul nome file, cat copia l’input standard nell’output standard, quindi vediamo ripetuta la nostra riga di testo. Possiamo usare questo comportamento per creare brevi file di testo.
Supponiamo di voler creare un file chiamato lazy_dog.txt contenente il testo nel nostro esempio.

Faremmo questo:
[me @ linuxbox ~] $ cat> lazy_dog.txt
La volpe marrone veloce saltò sul cane pigro.
Usando l’operatore < reindirizzamento, cambiamo l’origine dell’input standard dalla tastiera nel file lazy_dog.txt.

Vediamo che il risultato è lo stesso del passaggio di un singolo argomento del nome file. Ciò non è particolarmente utile rispetto al passare un argomento del nome file, ma serve a dimostrare l’utilizzo di un file come fonte di input standard. Altri comandi fanno un uso migliore dell’input standard, come vedremo presto.
Prima di andare avanti, controlla la pagina man di cat perché ha diverse opzioni interessanti.

Pipelines
La capacità dei comandi di leggere i dati dall’input standard e di inviarli all’output standard è sfruttata da una funzione shell chiamata pipeline.
Usando l’operatore pipe |, l’output standard di un comando può essere reindirizzato all’input standard di un altro.
comando1 | comando2
Per dimostrarlo appieno, avremo bisogno di alcuni comandi.
Ricordi come abbiamo detto che ce n’era uno che già conosceva e che accettava input standard? È less.
Possiamo usare less per visualizzare, pagina per pagina, l’output di qualsiasi comando che invia i suoi risultati all’output standard.

[me @ linuxbox ~] $ ls -l / usr / bin | less

Usando questa tecnica, possiamo esaminare convenientemente l’output di qualsiasi comando che produce output standard.

Filtri
Le pipeline sono spesso utilizzate per eseguire operazioni complesse sui dati.
È possibile riunire più comandi in una pipeline. Spesso i comandi utilizzati in questo modo vengono definiti filtri. I filtri accettano l’input, lo modificano in qualche modo e quindi lo producono. Il primo che proveremo è l’ordinamento. Immagina di voler fare un elenco combinato di tutti i programmi eseguibili in / bin e / usr / bin, mettili in ordine e visualizza l’elenco risultante.

[me @ linuxbox ~] $ ls / bin / usr / bin | ordina | less

Poiché abbiamo specificato due directory (/ bin e / usr / bin), l’output di ls sarebbe consistito in due elenchi ordinati, uno per ogni directory. Includendo l’ordinamento nella nostra pipeline, abbiamo modificato i dati per produrre un unico elenco ordinato.

La differenza tra > e |
A prima vista, può essere difficile comprendere il reindirizzamento eseguito dall’operatore della pipeline | contro l’operatore di reindirizzamento>. In poche parole, l’operatore di reindirizzamento collega un comando con un file, mentre l’operatore della pipeline collega l’output di un comando con l’input di un secondo comando.

comando1> file1
comando1 | comando2

Molte persone proveranno quanto segue quando apprenderanno le pipeline, “solo per vedere cosa succede”:
comando1> comando2
Risposta: a volte qualcosa di veramente brutto.
Ecco un esempio reale inviato da un lettore che stava amministrando un’appliance server basata su Linux.
Come superutente, ha fatto questo:
# cd / usr / bin
# ls> less
Il primo comando lo ha messo nella directory in cui sono memorizzati la maggior parte dei programmi, e il secondo comando ha detto alla shell di sovrascrivere il file less con l’output del comando ls. Poiché la directory / usr / bin conteneva già un file chiamato less (il programma less), il secondo comando sovrascriveva il file less con il testo di ls, distruggendo così il programma less sul suo sistema.
La lezione qui è che l’operatore di reindirizzamento crea o sovrascrive silenziosamente i file, quindi è necessario trattarli con molta attenzione.

uniq: segnala o omette le linee ripetute

Il comando uniq viene spesso utilizzato insieme a sort.
uniq accetta un elenco ordinato di dati dall’input standard o da un singolo argomento del nome file (vedere la pagina man uniq per i dettagli) e, per impostazione predefinita, rimuove qualsiasi duplicato dall’elenco.
Quindi, per assicurarci che il nostro elenco non abbia duplicati (ovvero qualsiasi programma con lo stesso nome che appare nelle directory / bin e / usr / bin), aggiungeremo uniq alla nostra pipeline.

[me @ linuxbox ~] $ ls / bin / usr / bin | ordina | uniq | less

In questo esempio, utilizziamo uniq per rimuovere eventuali duplicati dall’output del comando sort.
Se invece vogliamo vedere l’elenco dei duplicati, aggiungeremo l’opzione -d a uniq in questo modo:

[me @ linuxbox ~] $ ls / bin / usr / bin | ordina | uniq -d | less

wc: stampa, conteggi di righe, parole e byte

Il comando wc (conteggio parole) viene utilizzato per visualizzare il numero di righe,
parole e byte contenuti nei file. Ecco un esempio:
[me @ linuxbox ~] $ wc ls-output.txt
7902 64566 503634 ls-output.txt
In questo caso, stampa tre numeri: righe, parole e byte contenuti in ls-output.txt.
Come i nostri comandi precedenti, se eseguito senza argomenti della riga di comando, wc accetta input standard.
L’opzione -l limita il suo output per riportare solo righe.
L’aggiunta a una pipeline è un modo pratico per contare le cose.
Per vedere il numero di articoli che abbiamo nel nostro elenco ordinato, possiamo fare questo:

[me @ linuxbox ~] $ ls / bin / usr / bin | sort | uniq | wc -l
2728

grep: linee di stampa corrispondenti a un motivo
grep è un potente programma utilizzato per trovare schemi di testo all’interno dei file.
Si usa così:
nome file modello grep
Quando grep incontra uno “schema” nel file, stampa le linee che lo contengono.
I pattern che grep può abbinare possono essere molto complessi, ma per ora ci concentreremo su semplici corrispondenze di testo. Tratteremo i modelli avanzati, chiamati espressioni regolari, nel Capitolo 19. Supponiamo di voler trovare tutti i file nel nostro elenco di programmi che includessero la parola zip incorporata nel nome.
Tale ricerca potrebbe darci un’idea di alcuni dei programmi sul nostro sistema che avevano a che fare con la compressione dei file.

Dobbiamo digitare:

[me @ linuxbox ~] $ ls / bin / usr / bin | ordina | uniq | zip grep
bunzip2
bzip2
gunzip
gzip
unzip
zip
zipcloak
zipgrep
zipinfo
zipnote
zipsplit

Ci sono un paio di opzioni utili per grep.
• -i, che fa sì che grep ignori il caso durante l’esecuzione della ricerca (normalmente le ricerche fanno distinzione tra maiuscole e minuscole)
• -v, che dice a grep di stampare solo quelle linee che non corrispondono al modello

head / tail: stampa la prima / ultima parte dei file

A volte non vuoi tutto l’output di un comando.
Potresti voler solo le prime poche righe o le ultime poche righe.
Il comando head stampa le prime 10 righe di un file e il comando tail stampa le ultime 10 righe.
Per impostazione predefinita, entrambi i comandi stampano 10 righe di testo, ma questo può essere regolato con l’opzione -n.

[me @ linuxbox ~] $ head -n 5 ls-output.txt
totale 343496
-rwxr-xr-x 1 radice radice 31316 2017-12-05 08:58 [
-rwxr-xr-x 1 radice radice 8240 2017-12-09 13:39 411toppm
-rwxr-xr-x 1 radice radice 111276 2017-11-26 14:27 a2p
-rwxr-xr-x 1 radice radice 25368 2016-10-06 20:16 a52dec
[me @ linuxbox ~] $ tail -n 5 ls-output.txt
-rwxr-xr-x 1 radice radice 5234 2017-06-27 10:56 znew
-rwxr-xr-x 1 radice radice 691 2015-09-10 04:21 zonetab2pot.py
-rw-r – r– 1 radice radice 930 2017-11-01 12:23 zonetab2pot.pyc
-rw-r – r– 1 radice radice 930 2017-11-01 12:23 zonetab2pot.pyo
lrwxrwxrwx 1 root root 6 2016-01-31 05:22 zsoelim -> soelim

Questi possono essere utilizzati anche nelle pipelines:

[me @ linuxbox ~] $ ls / usr / bin | coda -n 5
znew
zonetab2pot.py
zonetab2pot.pyc
zonetab2pot.pyo
zsoelim

tail possiede un’opzione che permette di visualizzare i file in tempo reale.
Ciò è utile per controllare lo stato di avanzamento dei file di registro mentre vengono scritti. Nel seguente esempio, esamineremo il file dei messaggi in / var / log (o il file / var / log / syslog se mancano i messaggi). I privilegi di superutente sono necessari per eseguire questa operazione su alcune distribuzioni Linux poiché il file / var / log / messages potrebbe contenere informazioni sulla sicurezza.

[[email protected] ~]$ tail -f /var/log/messages
Feb 8 13:40:05 twin4 dhclient: DHCPACK from 192.168.1.1
Feb 8 13:40:05 twin4 dhclient: bound to 192.168.1.4 — renewal in 1652 seconds.
Feb 8 13:55:32 twin4 mountd[3953]: /var/NFSv4/musicbox exported to both 192.168.1.0/24 and
twin7.localdomain in 192.168.1.0/24,twin7.localdomain
Feb 8 14:07:37 twin4 dhclient: DHCPREQUEST on eth0 to 192.168.1.1 port 67
Feb 8 14:07:37 twin4 dhclient: DHCPACK from 192.168.1.1
Feb 8 14:07:37 twin4 dhclient: bound to 192.168.1.4 — renewal in 1771 seconds.
Feb 8 14:09:56 twin4 smartd[3468]: Device: /dev/hda, SMART Prefailure Attribute: 8 Seek_Time_
Performance changed from 237 to 236
Feb 8 14:10:37 twin4 mountd[3953]: /var/NFSv4/musicbox exported to both 192.168.1.0/24 and
twin7.localdomain in 192.168.1.0/24,twin7.localdomain
Feb 8 14:25:07 twin4 sshd(pam_unix)[29234]: session opened for user me by (uid=0)
Feb 8 14:25:36 twin4 su(pam_unix)[29279]: session opened for user root by me(uid=500)

Usando l’opzione -f, tail continua a monitorare il file e quando nuove linee vengono aggiunte, appaiono immediatamente sul display.
Questo continua finché non si digita ctrl-C.

tee: leggi da Stdin e output su Stdout e file

In linea con la nostra metafora idraulica, Linux fornisce un comando chiamato tee che crea un raccordo a “tee” sul nostro tubo.
Il programma tee legge l’input standard e lo copia sia sull’output standard (consentendo ai dati di continuare lungo la pipeline) sia su uno o più file. Ciò è utile per acquisire i contenuti di una pipeline in una fase intermedia di elaborazione.

Qui ripetiamo uno dei nostri esempi precedenti, questa volta includendo tee per acquisire l’intero elenco di directory nel file ls.txt prima che grep filtra il contenuto della pipeline:

[me @ linuxbox ~] $ ls / usr / bin | tee ls.txt | zip grep
bunzip2
bzip2
gunzip
gzip
Unzip
zip
zipcloak
zipgrep
ZipInfo
zipnote
zipsplit

Riassumendo
Come sempre, controlla la documentazione di ciascuno dei comandi che abbiamo trattato in questo capitolo.  Abbiamo visto solo il loro utilizzo più basilare. Tutti hanno una serie di opzioni interessanti. Man mano che acquisiamo  Esperienza su Linux, vedremo che la funzione di reindirizzamento della riga di comando è estremamente utile per risolvere problemi specializzati. Esistono molti comandi che utilizzano input e output standard e quasi tutti i programmi della riga di comando usano errori standard per visualizzare i loro messaggi informativi.

Translate »