Tracce
/
Bash
Bash
/
Programma
/
Here document
He

Here document in Bash

{one: "1 esercizio", many: "%{count} esercizi", other: "%{count} esercizi"}

Informazioni su Here document

Nella scrittura di script Bash, un «here document» (o «heredoc») reindirizza più righe di input a un comando o a un programma, come se le stessi digitando direttamente nel terminale. È uno strumento potente per incorporare testo su più righe all'interno degli script senza bisogno di file esterni o di manipolazioni complesse delle stringhe.

Caratteristiche principali e sintassi

  1. Delimitatore: un heredoc inizia con l'operatore << seguito da una parola delimitatrice (spesso chiamata «marcatore» o «terminatore»). Questa parola delimitatrice può essere qualsiasi parola tu scelga, ma è comune usarne una come EOF, END o TEXT per chiarezza. Per avere un codice più leggibile, puoi usare come delimitatore qualcosa di descrittivo, per esempio END_INSTALLATION_INSTRUCTIONS.

  2. Contenuto: dopo il << DELIMITER iniziale, scrivi il contenuto che vuoi reindirizzare. Può essere più righe di testo, codice o qualsiasi altra cosa.

  3. Terminazione: l'heredoc termina quando la parola delimitatrice compare di nuovo su una riga da sola, senza spazi bianchi iniziali o finali.

Sintassi di base

command << DELIMITER
  Content line 1
  Content line 2
  ...
  Content line N
DELIMITER

Come funziona

  • Bash legge tutte le righe tra il << DELIMITER iniziale e il DELIMITER finale.
  • Bash collega questo contenuto all'input standard del comando.
  • Il comando elabora questo input come se arrivasse dalla tastiera.

Esempio 1: output di semplice testo

cat << EOF
This is the first line.
This is the second line.
This is the third line.
EOF

Output:

This is the first line.
This is the second line.
This is the third line.

In questo esempio:

  • cat è il comando.
  • << EOF avvia l'heredoc con EOF come delimitatore.
  • Le tre righe di testo sono il contenuto.
  • EOF su una riga da sola termina l'heredoc.
  • cat scrive poi in output il contenuto che ha ricevuto.

Esempio 2: uso con wc (conteggio parole)

wc -l << END
Line 1
Line 2
Line 3
END

Output:

3

Qui wc -l conta il numero di righe. L'heredoc fornisce le tre righe come input.

Esempio 3: passare dati a uno script

Lo script:

#!/usr/bin/env bash

# Script to process input
while IFS= read -r line; do
  echo "Processing: $line"
done

Chiama lo script da un prompt bash interattivo con un heredoc:

./your_script << MY_DATA
Item 1
Item 2
Item 3
MY_DATA

Output:

Processing: Item 1
Processing: Item 2
Processing: Item 3

Varianti e funzionalità avanzate

Contenuto letterale

Bash esegue l'espansione delle variabili, la sostituzione dei comandi e l'espansione aritmetica all'interno di un heredoc. In questo senso, gli heredoc si comportano come le stringhe tra doppi apici.

cat << EOF
The value of HOME is $HOME
The current date is $(date)
Two plus two is $((2 + 2))
EOF

Output:

The value of HOME is /home/glennj
The current date is Thu Apr 24 13:47:32 EDT 2025
Two plus two is 4

Quando il delimitatore è tra apici (con virgolette singole o doppie), queste espansioni non avvengono. Il contenuto viene preso alla lettera. È come con le stringhe tra apici singoli.

cat << 'EOF'
The value of $HOME is not expanded here.
The result of $(date) is not executed.
Two plus two is calculated by $((2 + 2))
EOF

Output:

The value of $HOME is not expanded here.
The result of $(date) is not executed.
Two plus two is calculated by $((2 + 2))

Rimuovere le tabulazioni iniziali

Se usi <<- (con un trattino finale) invece di <<, Bash rimuove i caratteri di tabulazione iniziali da ogni riga dell'heredoc. È utile per indentare il contenuto dell'heredoc all'interno dello script senza influire sull'output.

# Note, the leading whitespace is tab characters only, not spaces!
# The ending delimiter can have leading tabs as well.
cat <<- END
	This line has 1 leading tab.
	  This line has a leading tab and some spaces.
		This line 2 leading tabs.
	END

L'output viene stampato con tutte le tabulazioni iniziali rimosse:

This line has 1 leading tab.
    This line has a leading tab and some spaces.
This line 2 leading tabs.
Caution

L'autore non consiglia questo uso. Anche se può migliorare la leggibilità dello script,

  1. è facile sostituire accidentalmente i caratteri di tabulazione con degli spazi (il tuo editor potrebbe farlo automaticamente), ed
  2. è difficile notare la differenza tra spazi e tabulazioni.

Quando usare gli here document

  • Input su più righe: quando devi fornire più righe di testo a un comando.
  • File di configurazione: incorporare piccoli frammenti di configurazione all'interno di uno script.
  • Generazione di codice: creare codice al volo all'interno di uno script.
  • Interazioni negli script: simulare l'input dell'utente per programmi interattivi.
  • Evitare file esterni: quando vuoi evitare di creare file temporanei.

Un uso tipico potrebbe essere fornire un testo di aiuto:

#!/usr/bin/env bash

usage() {
    cat << END_USAGE
Refresh database tables.

usage: ${0##*/} [-h|--help] [-A|--no-archive]

where: --no-archive flag will _skip_ the archive jobs
END_USAGE
}

# ... parsing command line options here ...

if [[ $flag_help == "true" ]]; then
  usage
  exit 0
fi

Svantaggi possibili

  • Documenti incorporati di grandi dimensioni possono rendere il codice più difficile da leggere. Può essere meglio rilasciare lo script con la documentazione in file separati.
  • Gli here document possono interrompere il flusso del codice. Potresti trovarti in una sezione di codice profondamente annidata quando vuoi passare del testo a un programma. L'indentazione dell'heredoc può apparire stridente rispetto al codice circostante.

Here string

Come gli here document, le here string (o «herestring») forniscono input a un comando. Tuttavia, mentre gli heredoc vengono forniti come un blocco di testo, le herestring vengono fornite come una singola stringa di testo. Le here string usano la sintassi <<< "text".

tr 'a-z' 'A-Z' <<< "upper case this string"

Output:

UPPER CASE THIS STRING

A differenza degli heredoc, non è richiesto un delimitatore finale.

Perché usare le here string?

Al posto di una here string si può usare una pipeline:

echo "upper case this string" | tr 'a-z' 'A-Z'

Quindi perché usare una here string?

Considera il caso in cui ottieni la stringa come output di un calcolo molto lungo e vuoi passare il risultato a due comandi separati. Usando le pipeline, devi eseguire il calcolo due volte:

some_long_running_calculation | first_command
some_long_running_calculation | second_command

Un approccio più efficiente è catturare l'output del calcolo (usando la sostituzione dei comandi) e usare le here string per fornire l'input ai due comandi successivi:

result=$( some_long_running_calculation )
first_command <<< "$result"
second_command <<< "$result"

Ecco un'applicazione reale di quell'esempio:

  • catturare la risposta JSON a una query REST API (che è paginata),
  • fornire i dati JSON a un programma jq per analizzare i risultati e scriverli in un file, e poi
  • fornire i dati JSON a un altro programma jq per determinare l'URL della query successiva.
# initialize the output CSV file
echo "ID,VALUE" > data.csv

url='https//example.com/api/query?page=1'

while true; do
  json=$( curl "$url" )

  # convert the results part of the response into CSV
  jq -r '.results[] | [.id, .value] | @csv' <<< "$json"

  # get the URL for the next page
  url=$( jq -r '.next_url // ""' <<< "$json" )
  if [[ "$url" == "" ]]; then
    break
  fi
done >> data.csv

Nota la posizione del reindirizzamento dell'output. Tutto l'output del ciclo while viene aggiunto al file data.csv.

Heredoc e herestring come reindirizzamento

Dato che sono solo forme di reindirizzamento, si possono combinare con altre operazioni di reindirizzamento:

cat <<< END_OF_TEXT > output.txt
This is my important text.
END_OF_TEXT

awk '...' <<< "$my_var" >> result.csv

In sintesi

Gli here document (o «heredoc») sono un modo flessibile e comodo per gestire input su più righe negli script Bash. Semplificano il processo di incorporare testo e dati direttamente negli script, rendendoli più autonomi e più facili da leggere.

Le here string (o «herestring») sono simili agli here document, ma offrono una sintassi più semplice e più dinamica.

Modifica tramite GitHub Il collegamento si apre in una nuova finestra o scheda