Skip to main content
  1. Concetti/

Command Grouping - {}

·3 mins
Alessio Barnini
Author
Alessio Barnini
Table of Contents

Cosa fa
#

Le graffe {} raggruppano piu' comandi in un unico stdout. La pipe che segue riceve tutto l'output come se venisse da un comando solo — una connessione, tutti i dati dentro.


TL;DR
#

# Senza {}: ogni comando pipe separatamente → N connessioni
echo "riga 1" | nc localhost 30002
echo "riga 2" | nc localhost 30002

# Con {}: un solo stdout → una connessione
{
    echo "riga 1"
    echo "riga 2"
} | nc localhost 30002

La regola: {} sta dove si fanno le domande — chi riceve i dati non deve sapere quanti comandi li hanno generati.


Come funziona — il flusso
#

graph LR
    subgraph Blocco["{ } — stdout unificato"]
        C1[echo riga 1]
        C2[echo riga 2]
        C3[echo riga 3]
    end
    Blocco -->|pipe unica| NC[nc localhost 30002]
    NC --> Output[risposta server]

Senza le graffe ogni echo | nc aprirebbe una connessione TCP separata. Con le graffe nc riceve un unico stdin con tutte le righe in sequenza.


Sintassi — regole obbligatorie
#

# Formato multi-riga (piu' leggibile)
{
    comando1
    comando2
    comando3
} | pipe-destinazione

# Formato inline (tutto su una riga)
{ comando1; comando2; comando3; } | pipe-destinazione
# OBBLIGATORIO inline:
# - spazio dopo {
# - spazio prima di }
# - punto e virgola dopo l'ultimo comando

Differenza con () — subshell
#

# {} — stesso processo, stesso ambiente
# le variabili definite dentro sono visibili fuori
{ x=5; echo $x; }
echo $x   # stampa 5

# () — subshell separata
# le variabili definite dentro NON sono visibili fuori
(x=5; echo $x)
echo $x   # stampa niente — x non esiste fuori

Per mandare dati a nc usa sempre {} — piu' leggero, stesso processo.


Casi d'uso
#

Brute force su una connessione sola — Bandit 24:

psw="password_bandit24"
{
    seq -f "%04g" 0 9999 | while read pin; do
        echo "$psw $pin"
    done
} | nc localhost 30002 | grep -v Wrong

Report con piu' comandi in un solo file:

{
    echo "=== $(date) ==="
    cat /var/log/auth.log | grep "Failed"
    echo "=== fine ==="
} > report.log

Redirect di stderr e stdout insieme da un blocco:

{
    comando_pericoloso
    altro_comando
} &> tutto.log

Il while dentro la pipe
#

Un caso speciale che confonde: il while genera righe, quelle righe diventano stdin del comando dopo la pipe:

# Il while e' dentro una pipe — il suo stdout fluisce a nc
seq 0 9999 | while read pin; do
    echo "$psw $pin"
done | nc localhost 30002

Qui non servono le graffe perche' il while e' gia' dentro una pipe. Le graffe servono quando vuoi raggruppare piu' comandi distinti.


Scenario Reale
#

# Analisi log — raggruppa piu' grep in un unico output
{
    grep "Failed password" /var/log/auth.log
    grep "Invalid user" /var/log/auth.log
    grep "Connection closed" /var/log/auth.log
} | sort | uniq -c | sort -rn | head -20
# tutti i pattern di attacco SSH, ordinati per frequenza
Tip

Regola pratica: se stai per scrivere lo stesso comando di destinazione tre volte (es. | nc, | grep, >> file) per comandi diversi, fermati e usa {} — lo scrivi una volta sola.


Collegato a
#

  • standard-streams — stdout, stdin, pipe
  • netcat — destinazione tipica del raggruppamento
  • seq — generatore di sequenze usato dentro i blocchi
  • bandit-24 — caso d'uso reale
  • system — categoria

Related