Skip to main content
  1. Concetti/

Standard Streams

·5 mins
Alessio Barnini
Author
Alessio Barnini
Table of Contents

Cosa fa
#

Ogni processo Linux apre automaticamente tre canali di comunicazione identificati da un numero (File Descriptor). Capire questi canali permette di separare output da errori, salvare risultati su file e collegare piu' comandi tra loro.


I tre canali
#

Ogni canale ha un numero identificativo chiamato File Descriptor (FD).

FDNomeDescrizioneSimbolo redirezione
0stdinInput che il comando riceve (tastiera o pipe)<
1stdoutOutput corretto prodotto dal comando> o 1>
2stderrMessaggi di errore e diagnostica2>

Redirezione — operatori completi
#

OperatoreCosa fa
comando > filestdout → file (overwrite)
comando >> filestdout → file (append, preserva contenuto)
comando < filefile → stdin del comando
comando 2> filestderr → file
comando 2>/dev/nullstderr → cestino (nasconde errori)
comando 2>&1stderr → dove va stdout
comando > file 2>&1stdout e stderr → stesso file (forma lunga)
comando &> filestdout e stderr → file (forma abbreviata)
comando &>> filestdout e stderr → file (append)

2>&1 — come funziona
#

2>&1 dice al kernel: manda stderr dove sta andando stdout. Il simbolo & prima del numero indica che e' un file descriptor, non un file chiamato "1".

# Salva tutto in un log — forma lunga:
comando > file.log 2>&1
# 1. stdout → file.log
# 2. stderr → dove va stdout → file.log

# Forma abbreviata equivalente:
comando &> file.log

L'ordine conta con la forma lunga:

# CORRETTO — prima ridirige stdout, poi aggancia stderr
comando > file.log 2>&1

# SBAGLIATO — stderr si aggancia a stdout (terminale)
#             poi stdout va al file, ma stderr resta sul terminale
comando 2>&1 > file.log

Con &> non hai questo problema — e' sempre corretto.


&> — redirect tutti i canali
#

&> e' la versione moderna e abbreviata di > file 2>&1. Il simbolo & prima di > significa "tutti i canali".

# Scarta tutto — stdout e stderr nel cestino:
comando &> /dev/null

# Caso tipico — cron job silenzioso:
* * * * * bandit24 /usr/bin/script.sh &> /dev/null
# senza &>/dev/null cron manda una email per ogni output

/dev/null — il cestino
#

File speciale del kernel — tutto quello che ci scrivi sparisce. Non occupa spazio, non rallenta nulla.

# Scarta solo gli errori, tieni stdout visibile:
find / -name "*.conf" 2>/dev/null

# Scarta tutto:
comando &> /dev/null

# Tieni solo gli errori, scarta stdout:
comando > /dev/null

< vs > — direzione dei dati
#

# > spinge stdout verso un file
echo "ciao" > file.txt       # il comando produce, il file conserva

# < tira il contenuto di un file dentro stdin
wc -l < file.txt             # il file fornisce, il comando elabora

>> vs > — append vs overwrite
#

# > overwrite — svuota il file prima di scrivere
echo "mela" > lista.txt      # lista.txt contiene solo "mela"

# >> append — aggiunge in coda senza cancellare
echo "pera" >> lista.txt     # lista.txt contiene "mela" e "pera"

Raggruppamento con
#

Puoi ridirigere l'output di piu' comandi in un unico blocco:

{
  echo "=== inizio ==="
  cat /etc/passwd
  echo "=== fine ==="
} &> report.log
# tutto il blocco va in report.log

Operatori di controllo shell
#

OperatoreNomeCosa fa
|pipecollega stdout di un comando allo stdin del successivo
&backgroundlancia il comando in background, terminale libero subito
&&AND logicoesegue il secondo solo se il primo ha exit code 0
||OR logicoesegue il secondo solo se il primo ha fallito (contrario di &&)
# pipe — collega comandi
cat /etc/passwd | grep root | cut -d: -f1

# & — background
cp file_grande.iso /backup/ &    # copia in background
jobs                             # vedi processi in background
fg                               # riporta in foreground

# && — AND logico, si ferma al primo errore
mkdir /backup && cp *.log /backup/

# || — OR logico, fallback
cd /backup || mkdir /backup

Differenza critica tra & e &&:

& significa "vai in background, non mi interessa se hai successo". && significa "vai avanti solo se il primo e' andato bene".


UUOC — Useless Use of Cat
#

Usare cat per leggere un file e passarlo via pipe quando il comando potrebbe leggerlo direttamente e' inefficiente — crea un processo extra.

# inefficiente:
cat data.txt | grep "millionth"

# efficiente:
grep "millionth" data.txt
grep "millionth" < data.txt

Scenario Reale
#

# Script di backup notturno — tutto in un log
tar -czf backup.tar.gz /data &>> /var/log/backup.log
# successi e errori finiscono tutti nel log

# Ricerca senza errori di permesso:
find / -perm -4000 -type f 2>/dev/null

# Debug di uno script cron:
* * * * * /usr/bin/myscript.sh &>> /tmp/debug.log
# quando funziona, cambia in &> /dev/null
Warning

&> /dev/null nasconde anche gli errori. Durante il debug usa &>> /tmp/debug.log per vedere cosa succede, poi rimetti /dev/null quando tutto funziona.

Tip

UUOC: se stai per scrivere cat file | comando, fermati. Quasi sempre puoi scrivere comando file o comando < file risparmiando un processo.


Collegato a
#

  • system — categoria
  • find — usa 2>/dev/null per nascondere permission denied
  • tee — scrive su stdout e su file contemporaneamente
  • bash — gli stream sono fondamentali per lo scripting

Related