GNU/Linux >> Linux Esercitazione >  >> Linux

Spiegazione:input, output e reindirizzamento degli errori in Linux

Se hai familiarità con i comandi di base di Linux, dovresti anche imparare il concetto di reindirizzamento dell'input e dell'output.

Sai già come funziona un comando Linux. Prende un input e ti dà un output. Ci sono alcuni giocatori nella scena qui. Lascia che te ne parli.

Stdin, stdout e stderr

Quando esegui un comando Linux, ci sono tre flussi di dati che giocano un ruolo in esso:

  • L'input standard (stdin) è l'origine dei dati di input. Per impostazione predefinita, stdin è qualsiasi testo immesso dalla tastiera. Il suo ID stream è 0.
  • L'output standard (stdout) è il risultato del comando. Per impostazione predefinita, viene visualizzato sullo schermo. Il suo ID stream è 1.
  • L'errore standard (stderr) è il messaggio di errore (se presente) prodotto dai comandi. Per impostazione predefinita, sullo schermo viene visualizzato anche stderr. Il suo ID stream è 2.

Questi flussi contengono i dati in testo normale in quella che viene chiamata memoria buffer.

Pensalo come un flusso d'acqua. Hai bisogno di una fonte d'acqua, un rubinetto per esempio. Ci colleghi un tubo e puoi conservarlo in un secchio (file) o innaffiare le piante (stamparlo). Puoi anche collegarlo a un altro rubinetto, se necessario. Fondamentalmente, stai reindirizzando l'acqua.

Linux ha anche questo concetto di reindirizzamento, in cui puoi reindirizzare stdin, stdout e stderr dalla sua destinazione abituale a un altro file o comando (o anche dispositivi periferici come le stampanti).

Lascia che ti mostri come funziona il reindirizzamento e come puoi usarlo.

Il reindirizzamento dell'output

La prima e più semplice forma di reindirizzamento è il reindirizzamento dell'output chiamato anche reindirizzamento stdout.

Sai già che per impostazione predefinita, l'output di un comando viene visualizzato sullo schermo. Ad esempio, uso il comando ls per elencare tutti i file e questo è l'output che ottengo:

[email protected]:~$ ls
appstxt  new.txt  static-ip.txt

Con il reindirizzamento dell'output, puoi reindirizzare l'output a un file. Se questo file di output non esiste, la shell lo creerà.

command > file

Ad esempio, permettetemi di salvare l'output del comando ls in un file denominato output.txt:

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

Il file di output viene creato in anticipo

Quale pensi che dovrebbe essere il contenuto di questo file di output? Permettimi di usare il comando cat per mostrarti una sorpresa:

[email protected]:~$ cat output.txt 
appstxt
new.txt
output.txt
static-ip.txt

Hai notato che l'inclusione di output.txt lì ? Ho scelto deliberatamente questo esempio per mostrartelo.

Il file di output a cui viene reindirizzato lo stdout viene creato prima dell'esecuzione del comando previsto. Come mai? Perché deve avere la destinazione di output pronta a cui verrà inviato l'output.

Aggiungi invece di clobber

Un problema spesso ignorato è che se si reindirizza a un file già esistente, la shell cancellerà (clobber) prima il file. Ciò significa che il contenuto esistente del file di output verrà rimosso e sostituito dall'output del comando.

Puoi aggiungere, invece di sovrascriverlo, usando la>> sintassi di reindirizzamento.

command >> file

Suggerimento :puoi vietare il clobber nella sessione della shell corrente usando:set -C

Perché dovresti reindirizzare stdout? È possibile memorizzare l'output per riferimento futuro e analizzarlo in seguito. È particolarmente utile quando l'output del comando è troppo grande e occupa tutto lo schermo. È come raccogliere registri.

Reindirizzamento pipe

Prima di vedere il reindirizzamento stdin, dovresti conoscere il reindirizzamento delle pipe. Questo è più comune e probabilmente lo utilizzerai molto.

Con il reindirizzamento pipe, si invia lo standard output di un comando allo standard input di un altro comando.

command 1 | command 2

Lascia che ti mostri un esempio pratico. Supponiamo di voler contare il numero di file visibili nella directory corrente. Puoi usare ls -1 (è il numero uno, non la lettera L) per visualizzare i file nella directory corrente:

[email protected]:~$ ls -1
appstxt
new.txt
output.txt
static-ip.txt

Probabilmente sai già che il comando wc viene utilizzato per contare il numero di righe in un file. Se combini entrambi questi comandi con pipe, ecco cosa ottieni:

[email protected]:~$ ls -1 | wc -l
4

Con pipe, entrambi i comandi condividono lo stesso buffer di memoria. L'output del primo comando viene memorizzato nel buffer e lo stesso buffer viene quindi utilizzato come input per il comando successivo.

Vedrai il risultato dell'ultimo comando nella pipeline. Questo è ovvio perché lo stdout dei comandi precedenti viene inviato ai comandi successivi invece di andare sullo schermo.

Il reindirizzamento o il piping delle tubazioni non si limita alla connessione di due soli comandi. Puoi collegare più comandi purché l'output di un comando possa essere utilizzato come input del comando successivo.

command_1 | command_2 | command_3 | command_4

Ricorda che stdout/stdin è un blocco di dati, non nomi di file

Alcuni nuovi utenti Linux si confondono durante l'utilizzo del reindirizzamento. Se un comando restituisce un gruppo di nomi di file come output, non puoi usare quei nomi di file come argomento.

Ad esempio, se usi il comando trova per trovare tutti i file che terminano con .txt, non puoi passarlo tramite pipe per spostare i file trovati in una nuova directory, non direttamente in questo modo:

find . -type f -name "*.txt" | mv destination_directory

Questo è il motivo per cui vedrai spesso il comando find usato in coniugazione con il comando exec o xargs. Questi comandi speciali "convertono il testo con un gruppo di nomi di file in nomefile" che possono essere passati come argomento.

find . -type f -name "*.txt" | xargs -t -I{} mv {} ../new_dir

Il reindirizzamento dell'input

Puoi usare il reindirizzamento stdin per passare il contenuto di un file di testo a un comando come questo:

command < file

Non vedrai stdin essere usato molto. È perché la maggior parte dei comandi Linux accetta nomi di file come argomenti e quindi il reindirizzamento stdin spesso non è richiesto.

Prendi questo ad esempio:

head < filename.txt

Il comando precedente potrebbe essere stato solo head filename.txt (senza il <).

Non è che il reindirizzamento stdin sia completamente inutile. Alcuni comandi si basano su di esso. Prendi ad esempio il comando tr. Questo comando può fare molto ma nell'esempio seguente converte il testo di input da minuscolo a maiuscolo:

tr a-z A-Z < filename.txt

In effetti, l'uso dello stdin è consigliabile su pipe specialmente per evitare l'uso non necessario del comando cat.

Ad esempio, molte persone userebbero l'esempio sopra con cat e poi userebbero tr su di esso. Francamente, non c'è bisogno di usare cat qui.

cat filename.txt | tr a-z A-Z

Combina reindirizzamenti

Puoi combinare il reindirizzamento stdin, stdout e pipe secondo le tue necessità.

Ad esempio, il comando seguente elenca tutti i file .txt nella directory corrente, quindi conta di quei file .txt e salva l'output in un nuovo file.

ls *.txt | wc -l > count.txt

Reindirizzamento errore

A volte, quando esegui un comando o uno script, vedrai che viene visualizzato un messaggio di errore sullo schermo.

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

All'inizio di questo articolo, ho menzionato che ci sono tre flussi di dati e stderr è uno dei flussi di dati di output che viene visualizzato sullo schermo per impostazione predefinita.

Puoi anche reindirizzare lo stderr. Poiché si tratta di un flusso di dati di output, puoi utilizzare lo stesso simbolo di reindirizzamento> o>> che hai utilizzato per il reindirizzamento stdout.

Ma come distinguere tra stdout e stderr quando sono entrambi flussi di dati di output? Dal loro ID flusso (chiamato anche descrittore di file).

Flusso di dati ID flusso
stdin 0
uscita standard 1
stderr 2
-t, –elenco
-u, –aggiornamento
-x, –estrai, –ottieni
-j, –bzip2
-z, –gzip, –gunzip, –ungzip

Per impostazione predefinita, quando si utilizza il simbolo di reindirizzamento dell'output>, in realtà significa 1>. In parole, stai dicendo che il flusso di dati con ID 1 viene emesso qui.

Quando devi reindirizzare lo stderr, usi il suo ID come 2> o 2>>. Ciò significa che il reindirizzamento dell'output è per il flusso di dati stderr (ID 2).

Esempi di reindirizzamento Stderr

Ve lo mostro con alcuni esempi. Supponiamo che tu voglia solo salvare l'errore, puoi usare qualcosa del genere:

[email protected]:~$ ls fffff 2> error.txt
[email protected]:~$ cat error.txt 
ls: cannot access 'fffff': No such file or directory

Era semplice. Rendiamolo leggermente più complicato (e utile):

[email protected]:~$ ls -l new.txt ffff > output.txt 2> error.txt 
[email protected]:~$ cat output.txt 
-rw-rw-r-- 1 abhishek abhishek 0 May  5 10:25 new.txt
[email protected]:~$ cat error.txt 
ls: cannot access 'ffff': No such file or directory

Nell'esempio precedente, il comando ls tenta di visualizzare due file. Per un file ottiene successo e per l'altro, ottiene errore. Quindi quello che ho fatto qui è reindirizzare lo stdout su oput.txt (con>) e lo stderr su error.txt (con 2>).

Puoi anche reindirizzare sia stdout che stderr allo stesso file. Ci sono modi per farlo.

Nell'esempio seguente, invio prima lo stderr (con 2>>) al file combined.txt in modalità append. E poi, lo stdout (con>>) viene inviato allo stesso file in modalità append.

[email protected]:~$ ls -l new.txt fff 2>> combined.txt >> combined.txt 
[email protected]:~$ cat combined.txt 
ls: cannot access 'fff': No such file or directory
-rw-rw-r-- 1 abhishek abhishek 0 May  5 10:25 new.txt

Un altro modo, e questo è quello preferito, è usare qualcosa come 2>&1. Che può essere approssimativamente tradotto in "reindirizzare stderr allo stesso indirizzo di stdout".

Prendiamo l'esempio precedente e questa volta utilizziamo 2>&1 per reindirizzare sia stdout che stderr allo stesso file.

[email protected]:~$ ls -l new.txt fff > output.txt 2>&1
[email protected]:~$ cat output.txt 
ls: cannot access 'fff': No such file or directory
-rw-rw-r-- 1 abhishek abhishek 0 May  5 10:25 new.txt

Tieni presente che non puoi usare 2>>&1 pensando di usarlo in modalità append. 2>&1 va già in modalità di aggiunta.

Puoi anche usare prima 2> e poi usare 1>&2 per reindirizzare stdout allo stesso file di stderr. Fondamentalmente, è ">&" che reindirizza un flusso di dati a un altro.

Riepilogo

  • Ci sono tre flussi di dati. Un input, stdin (0) e due flussi di dati di output stdout (1) e stderr (2).
  • La tastiera è il dispositivo stdin predefinito e lo schermo è il dispositivo di output predefinito.
  • Il reindirizzamento dell'output viene utilizzato con> o>> (per la modalità di aggiunta).
  • Il reindirizzamento dell'input viene utilizzato con <.
  • Lo stderr può essere reindirizzato usando 2> o 2>>.
  • Lo stderr e lo stdout possono essere combinati usando 2>&1.

Dal momento che stai imparando il reindirizzamento, dovresti anche conoscere il comando tee. Questo comando consente di visualizzare l'output standard e di salvare su file contemporaneamente.

Spero che questa guida dettagliata sul reindirizzamento in Linux ti sia piaciuta. Se hai ancora dubbi o se hai suggerimenti per migliorare questo articolo, faccelo sapere nella sezione commenti.


Linux
  1. Spiegazione approfondita del comando della cronologia in Linux

  2. Reindirizzamento input/output in Linux/Unix

  3. ls Command in Linux:17 esempi utili spiegati

  4. Pipe e reindirizzamento in Linux - Spiegazione!

  5. Come interpretare e correggere un errore di input/output in Linux?

Spiegazione del comando sorgente su Linux

Spiegazione del reindirizzamento di input e output su Linux

Spiegazione del comando dello schermo su Linux

Spiegazione del comando Arping su Linux

Shell Scripting Part4 – Input, Output e Reindirizzamento

Esempi di comandi echo Linux