Tracks
/
Bash
Bash
/
Lehrplan
/
Here-Dokumente
He

Here-Dokumente in Bash

{one: "1 Übung", other: "%{count} Übungen"}

Über Here-Dokumente

In der Bash-Skripterstellung leitet ein „Here-Dokument“ (oder „Heredoc“) mehrere Eingabezeilen an einen Befehl oder ein Programm um, als würdest du sie direkt im Terminal eintippen. Es ist ein leistungsfähiges Werkzeug, um mehrzeiligen Text in deine Skripte einzubetten, ohne externe Dateien oder komplizierte String-Manipulation zu brauchen.

Wichtige Merkmale und Syntax

  1. Trennzeichen: Ein Heredoc beginnt mit dem Operator <<, gefolgt von einem Trennwort (oft „Marker“ oder „Terminator“ genannt). Dieses Trennzeichen kann ein beliebiges Wort sein, aber üblicherweise nimmst du etwas wie EOF, END oder TEXT, damit es klar erkennbar ist. Für besser lesbaren Code kannst du etwas Beschreibendes als Trennzeichen verwenden, zum Beispiel END_INSTALLATION_INSTRUCTIONS.

  2. Inhalt: Nach dem einleitenden << DELIMITER schreibst du den Inhalt, den du umleiten möchtest. Das können mehrere Zeilen Text, Code oder irgendetwas anderes sein.

  3. Ende: Das Heredoc endet, wenn das Trennwort erneut in einer eigenen Zeile auftaucht, ohne führende oder nachfolgende Leerzeichen.

Grundlegende Syntax

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

So funktioniert es

  • Bash liest alle Zeilen zwischen dem einleitenden << DELIMITER und dem abschließenden DELIMITER.
  • Bash verbindet diesen Inhalt mit der Standardeingabe des Befehls.
  • Der Befehl verarbeitet diese Eingabe, als käme sie von der Tastatur.

Beispiel 1: Einfache Textausgabe

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

Ausgabe:

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

In diesem Beispiel:

  • cat ist der Befehl.
  • << EOF startet das Heredoc mit EOF als Trennzeichen.
  • Die drei Textzeilen sind der Inhalt.
  • EOF in einer eigenen Zeile beendet das Heredoc.
  • Danach gibt cat den empfangenen Inhalt aus.

Beispiel 2: Verwendung mit wc (Wortzählung)

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

Ausgabe:

3

Hier zählt wc -l die Anzahl der Zeilen. Das Heredoc liefert die drei Zeilen als Eingabe.

Beispiel 3: Daten an ein Skript übergeben

Das Skript:

#!/usr/bin/env bash

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

Rufe das Skript mit einem Heredoc von einer interaktiven Bash-Eingabeaufforderung aus auf:

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

Ausgabe:

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

Varianten und fortgeschrittene Funktionen

Wörtlicher Inhalt

Bash führt innerhalb eines Heredocs Variablenexpansion, Befehlssubstitution und arithmetische Expansion durch. In diesem Sinn verhalten sich Heredocs wie Strings in doppelten Anführungszeichen.

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

Ausgabe:

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

Wenn das Trennzeichen in Anführungszeichen steht (einfache oder doppelte Anführungszeichen), werden diese Expansionen verhindert. Der Inhalt wird wörtlich genommen. Das ist wie bei Strings in einfachen Anführungszeichen.

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

Ausgabe:

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

Führende Tabs entfernen

Wenn du <<- (mit einem Bindestrich am Ende) statt << verwendest, entfernt Bash alle führenden Tabulatorzeichen aus jeder Zeile des Heredocs. Das ist nützlich, um den Heredoc-Inhalt in deinem Skript einzurücken, ohne die Ausgabe zu beeinflussen.

# 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

Die Ausgabe wird ohne alle führenden Tabs gedruckt:

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

Der Autor empfiehlt diese Verwendung nicht. Sie kann zwar die Lesbarkeit des Skripts verbessern,

  1. aber es ist leicht, die Tabulatorzeichen versehentlich durch Leerzeichen zu ersetzen (dein Editor macht das vielleicht automatisch), und
  2. es ist schwer, den Unterschied zwischen Leerzeichen und Tabulatoren zu erkennen.

Wann du Here-Dokumente einsetzt

  • Mehrzeilige Eingabe: Wenn du einem Befehl mehrere Textzeilen übergeben musst.
  • Konfigurationsdateien: kleine Konfigurationsausschnitte in ein Skript einbetten.
  • Code generieren: Code spontan innerhalb eines Skripts erstellen.
  • Interaktionen skripten: Benutzereingaben für interaktive Programme simulieren.
  • Externe Dateien vermeiden: Wenn du das Anlegen temporärer Dateien vermeiden willst.

Ein typischer Anwendungsfall könnte sein, einen Hilfetext bereitzustellen:

#!/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

Mögliche Nachteile

  • Große eingebettete Dokumente können deinen Code schwerer lesbar machen. Manchmal ist es besser, dein Skript mit der Dokumentation in separaten Dateien auszurollen.
  • Here-Dokumente können den Fluss des Codes unterbrechen. Vielleicht bist du gerade in einem tief verschachtelten Codeabschnitt, wenn du etwas Text an ein Programm übergeben willst. Die Einrückung des Heredocs kann im Vergleich zum umgebenden Code störend wirken.

Here-Strings

Wie Here-Dokumente liefern Here-Strings (oder „Herestrings“) eine Eingabe an einen Befehl. Während Heredocs jedoch als Textblock übergeben werden, werden Herestrings als einzelner String übergeben. Here-Strings verwenden die Syntax <<< "text".

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

Ausgabe:

UPPER CASE THIS STRING

Anders als bei Heredocs ist kein abschließendes Trennzeichen nötig.

Warum Here-Strings verwenden?

Statt eines Here-Strings kannst du eine Pipeline verwenden:

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

Warum also einen Here-String verwenden?

Stell dir vor, du bekommst den String als Ausgabe einer lang laufenden Berechnung, und du willst das Ergebnis an zwei separate Befehle weitergeben. Mit Pipelines musst du die Berechnung zweimal ausführen:

some_long_running_calculation | first_command
some_long_running_calculation | second_command

Effizienter ist es, die Ausgabe der Berechnung aufzufangen (mit Befehlssubstitution) und Here-Strings zu verwenden, um die beiden nachfolgenden Befehle mit Eingabe zu versorgen:

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

Hier ist eine praktische Anwendung dieses Beispiels:

  • die JSON-Antwort einer (seitenweisen) REST-API-Abfrage erfassen,
  • die JSON-Daten an ein jq-Programm übergeben, um die Ergebnisse zu parsen und in eine Datei auszugeben, und dann
  • die JSON-Daten an ein weiteres jq-Programm übergeben, um die URL der nächsten Abfrage zu bestimmen.
# 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

Beachte die Position der Ausgabeumleitung. Alle Ausgaben der while-Schleife werden an die Datei data.csv angehängt.

Heredocs und Herestrings als Umleitung

Da es sich nur um Formen der Umleitung handelt, lassen sie sich mit anderen Umleitungsoperationen kombinieren:

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

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

Zusammenfassung

Here-Dokumente (oder „Heredocs“) sind eine flexible und bequeme Möglichkeit, mehrzeilige Eingaben in Bash-Skripten zu verwalten. Sie vereinfachen es, Text und Daten direkt in deine Skripte einzubetten, wodurch diese eigenständiger und leichter lesbar werden.

Here-Strings (oder „Herestrings“) sind wie Here-Dokumente, bieten aber eine einfachere und dynamischere Syntax.

Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab