Kurzusok
/
Bash
Bash
/
Tanterv
/
Here-dokumentumok
He

Here-dokumentumok ebben a kurzusban: Bash

{one: "1 feladat", other: "%{count} feladat"}

A(z) Here-dokumentumok fogalomról

A Bash-szkriptelésben a „here document” (vagy „heredoc”) a bemenet több sorát irányítja át egy parancsnak vagy programnak, mintha csak közvetlenül a terminálba gépelnéd be őket. Hatékony eszköz arra, hogy több soros szöveget ágyazz a szkriptjeidbe anélkül, hogy külső fájlokra vagy bonyolult stringkezelésre lenne szükség.

Fő jellemzők és szintaxis

  1. Határoló: a heredoc a << operátorral kezdődik, amelyet egy határoló szó követ (ezt szokás „jelölőnek” vagy „lezárónak” is nevezni). Ez a határoló bármilyen szó lehet, amit csak kiválasztasz, de az áttekinthetőség kedvéért gyakran olyasmit használnak, mint az EOF, az END vagy a TEXT. Olvashatóbb kód érdekében leíró határolót is választhatsz, például END_INSTALLATION_INSTRUCTIONS-t.

  2. Tartalom: a kezdeti << DELIMITER után írod le azt a tartalmat, amelyet át szeretnél irányítani. Ez lehet több sor szöveg, kód vagy bármi más.

  3. Lezárás: a heredoc akkor ér véget, amikor a határoló szó újra megjelenik egy sorban, egyedül, előtte és utána semmilyen szóköz vagy tabulátor nélkül.

Alap szintaxis

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

Hogyan működik

  • A Bash beolvassa az összes sort a kezdő << DELIMITER és a záró DELIMITER között.
  • A Bash ezt a tartalmat a parancs szabványos bemenetéhez kapcsolja.
  • A parancs úgy dolgozza fel ezt a bemenetet, mintha az a billentyűzetről érkezne.

1. példa: Egyszerű szövegkiírás

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

Kimenet:

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

Ebben a példában:

  • a cat a parancs.
  • A << EOF indítja a heredocot, a határoló pedig az EOF.
  • A három szövegsor a tartalom.
  • Az EOF egy külön sorban zárja le a heredocot.
  • A cat ezután kiírja a kapott tartalmat.

2. példa: Használat a wc paranccsal (szavak számlálása)

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

Kimenet:

3

Itt a wc -l a sorok számát számolja meg. A heredoc három sort ad bemenetként.

3. példa: Adatok átadása egy szkriptnek

A szkript:

#!/usr/bin/env bash

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

Hívd meg a szkriptet egy interaktív bash-parancssorból, heredoc segítségével:

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

Kimenet:

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

Variációk és haladó funkciók

Szó szerinti tartalom

A Bash a heredocon belül végrehajtja a változóbehelyettesítést, a parancsbehelyettesítést és az aritmetikai kiértékelést. Ebben az értelemben a heredocok úgy viselkednek, mint a kettős idézőjelbe tett stringek.

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

Kimenet:

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

Ha a határolót idézőjelbe teszed (szimpla vagy dupla idézőjellel), ezek a behelyettesítések elmaradnak. A tartalom szó szerint értelmeződik. Ez olyan, mint a szimpla idézőjelbe tett stringek esetében.

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

Kimenet:

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

Kezdő tabulátorok levágása

Ha a << helyett a <<--t használod (a végén lévő kötőjellel), a Bash leveszi a heredoc minden sorának elejéről a tabulátorkaraktereket. Ez akkor hasznos, ha a heredoc tartalmát behúzva szeretnéd elhelyezni a szkriptben anélkül, hogy ez a kimenetet befolyásolná.

# 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

A kimenet úgy jelenik meg, hogy az összes kezdő tabulátor eltűnt belőle:

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

A szerző nem javasolja ezt a használatot. Bár javíthatja a szkript olvashatóságát,

  1. könnyen előfordulhat, hogy a tabulátorkaraktereket véletlenül szóközökre cseréled (a szerkesztőd ezt automatikusan is megteheti), és
  2. nehéz észrevenni a különbséget a szóközök és a tabulátorok között.

Mikor használj heredocot

  • Többsoros bemenet: amikor több sor szöveget kell egy parancsnak átadnod.
  • Konfigurációs fájlok: kis konfigurációs részletek beágyazása egy szkriptbe.
  • Kódgenerálás: kód létrehozása menet közben egy szkripten belül.
  • Interakciók szkriptelése: felhasználói bemenet szimulálása interaktív programokhoz.
  • Külső fájlok elkerülése: amikor nem szeretnél ideiglenes fájlokat létrehozni.

Egy tipikus felhasználás a súgószöveg biztosítása:

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

Lehetséges hátrányok

  • A nagy beágyazott dokumentumok nehezebben olvashatóvá tehetik a kódot. Néha jobb, ha a szkriptet külön fájlokban lévő dokumentációval együtt élesíted.
  • A heredocok megtörhetik a kód menetét. Előfordulhat, hogy mélyen egymásba ágyazott kódrészben vagy, amikor szöveget szeretnél átadni egy programnak. A heredoc behúzása kiríhat a környező kódból.

Here stringek

A heredocokhoz hasonlóan a here stringek (vagy „herestringek”) is bemenetet adnak egy parancsnak. Míg azonban a heredocot szövegblokként adod meg, addig a here stringet egyetlen stringként. A here stringek a <<< "text" szintaxist használják.

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

Kimenet:

UPPER CASE THIS STRING

A heredocokkal ellentétben itt nincs szükség záró határolóra.

Miért használj here stringet?

Egy here string helyett csővezetéket is használhatsz:

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

Akkor miért használj here stringet?

Vegyük azt az esetet, amikor egy hosszan futó számítás kimeneteként kapod meg a stringet, és az eredményt két külön parancsnak szeretnéd átadni. Csővezetékek használatával kétszer kell lefuttatnod a számítást:

some_long_running_calculation | first_command
some_long_running_calculation | second_command

Hatékonyabb megközelítés, ha elmented a számítás kimenetét (parancsbehelyettesítéssel), majd here stringekkel adod meg a bemenetet a két következő parancsnak:

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

Íme egy valós példa erre:

  • elmented egy REST API-lekérdezés JSON-válaszát (amely több oldalból áll),
  • átadod a JSON-adatokat egy jq programnak, amely feldolgozza az eredményeket, és fájlba írja azokat, majd
  • átadod a JSON-adatokat egy másik jq programnak, hogy meghatározza a következő lekérdezés URL-jét.
# 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

Figyeld meg a kimenetátirányítás helyét. A while-ciklus összes kimenete a data.csv fájl végére fűződik.

A heredocok és a here stringek mint átirányítás

Mivel ezek csupán az átirányítás egy-egy formái, más átirányítási műveletekkel is kombinálhatók:

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

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

Összefoglalva

A heredocok rugalmas és kényelmes módot kínálnak a többsoros bemenet kezelésére Bash-szkriptekben. Egyszerűbbé teszik, hogy szöveget és adatokat közvetlenül a szkriptjeidbe ágyazz, így azok önállóbbak és könnyebben olvashatók lesznek.

A here stringek (vagy „herestringek”) a heredocokhoz hasonlók, de egyszerűbb, dinamikusabb szintaxist kínálnak.

Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg