Při práci s Bash skripty se můžete dostat do situace, kdy budete muset zpracovat řadu vstupů pomocí stejného příkazu. Naštěstí v Bash existuje způsob, jak toho dosáhnout optimálnějším způsobem pomocí HereDoc .
HereDoc, zkratka pro Zde dokument , je vstupní Přesměrování metoda pro předání více vstupů programu nebo příkazu. Pojem heredoc se netýká výhradně samotného Bashe. Mnoho populárních programovacích jazyků jako Perl, Ruby, PHP podporuje heredoc.
V tomto článku se podíváme na syntaxi a použití heredoc s některými případy použití v reálném světě. Všechny příklady v tomto článku jsou vytvořeny tak, aby byly jednoduché, takže tento koncept snadno pochopí i nováček. Pojďme do toho a začněme hrát s heredocem v Bash.
Syntaxe HereDoc
Následující diagram ilustruje syntaxi heredoc.
Tady,
- Příkaz - Jakýkoli příkaz (cat, wc, mail atd..), který přijímá přesměrování.
- Operátor přesměrování (
<<
) - Výchozí operátor pro HereDoc je<<
. Přesměruje blok kódu na příkaz ke zpracování. - Token oddělovače - Oddělovací token označuje začátek a konec dokumentu (blok kódu). Oddělovací token může být jakýkoli, ale měl by být identický. Obvykle uvidíte
EOF
se používá jako oddělovací tokeny, které znamenají „Konec toku souborů“.
Tisk víceřádkového řetězce pomocí HereDoc v Bash
Začněme jednoduchým příkladem přesměrování víceřádkového řetězce a jeho vytištění na terminál.
cat
příkaz přijímá proud vstupů as heredoc a blok kódu můžete přesměrovat a vytisknout jej na terminál.
$ cat << EOF Something is wrong with the input file received for today. Contact the downstream team to get it corrected. ==> SLA MISSED <== EOF
Výstup:
Something is wrong with the input file received for today. Contact the downstream team to get it corrected. ==> SLA MISSED <==
Podívejte se na výše uvedený fragment kódu. Mám tři řádky, které jsou přesměrovány na cat
příkaz. Používám EOF
jako oddělovač. Můžete však použít cokoli, jak chcete, ale počáteční a koncový oddělovač ponechte stejný.
Zkusme ještě jeden jednoduchý příklad. Přesměruji stejný tři řádek na počet slov program. Používám jiný oddělovač (BLK
) zde.
$ wc -l << BLK Something is wrong with the input file received for today. Contact the downstream team to get it corrected. ==> SLA MISSED <== BLK
Ukázkový výstup:
3
Přesměrování a propojení v HereDoc
Operátor přesměrování výstupu můžete zkombinovat s heredoc a přesměrovat výstup do souboru místo jeho tisku na terminál.
Používám stejný příklad, který jsem použil v předchozí části, a přesměruji výstup do souboru s názvem log_op.txt
.
$ cat << EOF > /tmp/log_op.txt Something is wrong with the input file received for today. Contact the downstream team to get it corrected. ==> SLA MISSED <== EOF
Výstup z heredoc lze odeslat do potrubí operátora k dalšímu zpracování.
$ cat << EOF | grep -i sla Something is wrong with the input file received for today. Contact the downstream team to get it corrected. ==> SLA MISSED <== EOF
Potlačení karet v HereDoc
Pokud jsou v bloku kódu bílé mezery (tabulátory) a chcete-li je potlačit, použijte "-"
po operátorovi přesměrování. Důležité je poznamenat, že budou potlačeny pouze tabulátory, nikoli mezery.
Podívejte se na níže uvedený příklad. Ke stejnému příkladu, který jsme viděli v předchozích částech, jsem přidal podmíněný příkaz. První dva řádky v heredoc jsou označeny záložkami (4) a třetí řádek je oddělený (2).
if [[ $x = "err" ]] then cat <<- err_msg 1. Something is wrong with the input file received for today. 2. Contact the downstream team to get it corrected. 3. ==> SLA MISSED <== err_msg fi
Po odeslání úryvku kódu bude můj výstup následující.
1. Something is wrong with the input file received for today. 2. Contact the downstream team to get it corrected. 3. ==> SLA MISSED <==
Jak vidíte, tabulátory řádku 1 a 2 jsou potlačeny, ale na řádku 3, protože jsou použity mezery, potlačeny nejsou.
Rozšíření proměnných a příkazů v HereDoc
Neznamená to, že v rámci bloku kódu heredoc můžete předávat pouze řetězce. V rámci bloku kódu můžete předávat uživatelem definované proměnné prostředí a spouštět příkazy.
Podívejte se na níže uvedený příklad. V bloku kódu mám jednu uživatelsky definovanou proměnnou "${AUTHOR}"
, jedna proměnná prostředí "${SHELL}"
, externí příkaz "whoami"
.
Po odeslání tohoto úryvku se proměnné a příkazy rozbalí a poté budou přesměrovány na cat
příkaz.
AUTHOR="OSTechNix" cat << EOF Author: ${AUTHOR} # USER DEFINED VARIABLE Article: Bash Heredoc I am using the ${SHELL} shell # ENV VARIABLE $(whoami) # EXTERNAL COMMAND EOF
Ukázkový výstup:
Author: OsTechnix Article: Bash Heredoc I am using the /bin/bash shell karthick
Počáteční oddělovač můžete uzavřít do jednoduchých uvozovek, abyste potlačili rozšíření v rámci bloku kódu. Tímto způsobem bude vše v bloku kódu považováno za řetězcový literál.
cat << 'EOF' Author: ${AUTHOR} # USER DEFINED VARIABLE Article: Bash Heredoc I am using the ${SHELL} shell # ENV VARIABLE $(whoami) # EXTERNAL COMMAND EOF
Ukázkový výstup:
Author: ${AUTHOR} Article: Bash Heredoc I am using the ${SHELL} shell $(whoami)
Víceřádkové komentáře s HereDoc
Jak už možná víte, Bash nepodporuje víceřádkové komentáře. Pomocí heredoc můžete vytvářet víceřádkové komentáře přesměrováním bloku kódu na no-op
příkaz (:
).
no-op
je vestavěný bash, který přebírá vstup a vrací výstupní kód nula. Můžete to považovat za synonymum k vestavěnému bash "true" což také ukončí návratový kód nula.
: << 'COMMENTS' Author : OStechnix Article : Bash Heredoc BashV : 5.1.4 OS : PoP!_OS COMMENTS
Pozor: Téměř každý textový editor má funkci výběru více řádků a umožňuje vám komentovat nebo odebírat komentáře pomocí stisknutí klávesy. Je lepší setrvat u tohoto přístupu.
Escapování speciálních znaků v HereDoc
Bloky kódu mohou obsahovat speciální znaky. Pokud chcete uniknout speciálním postavám, existuje několik způsobů, jak toho dosáhnout.
Oddělovač můžete uzavřít jako jednoduchý nebo dvojité uvozovky nebo předpona zpětné lomítko s oddělovačem. Tímto způsobem budou zakódovány všechny speciální znaky.
# SINGLE QUOTES ESCAPE cat << 'EOF' I am using the ${SHELL} shell # ENV VARIABLE $(whoami) # EXTERNAL COMMAND EOF
# DOUBLE QUOTES ESCAPE cat << "EOF" I am using the ${SHELL} shell # ENV VARIABLE $(whoami) # EXTERNAL COMMAND EOF
# BACKSLASH ESCAPE cat << \EOF I am using the ${SHELL} shell # ENV VARIABLE $(whoami) # EXTERNAL COMMAND EOF
Namísto escapování všech speciálních znaků můžete také speciální znaky v bloku escapovat přidáním zpětného lomítka před jakýmkoli speciálním znakem.
cat << EOF I am using the \${SHELL} shell # ENV VARIABLE $(whoami) # EXTERNAL COMMAND EOF
Ukázkový výstup:
I am using the ${SHELL} shell karthick
Případ použití HereDoc
Doposud jsme viděli základní konstrukci heredocu a jeho základní použití. Nyní se podívejme na některé případy použití v reálném životě. Podle mých zkušeností jsem heredoc používal při práci s ssh a databázovými klienty, kde musím spouštět skupinu příkazů.
Příklad 1:Spuštění jako jiný uživatel ve skriptu
V některých případech můžete chtít spouštět určité části kódu jako jiný uživatel. V takovém případě můžete použít heredoc k přesměrování příkazů ke spuštění jako jiný uživatel.
Podívejte se na níže uvedený příklad. Přesměruji blok kódu na su
příkaz, který přepne uživatele na "ostechnix" a vytvoří soubor s názvem test pokud neexistuje.
su - ostechnix << EOF if [[ ! -f /home/ostechnix/test ]];then touch /home/ostechnix/test echo "File Created" else echo "File exists" fi EOF
Příklad 2:Použití HereDoc s klientem DB
Když chcete spustit sérii příkazů proti databázi, heredoc se vám bude hodit.
Podívejte se na níže uvedený příklad. Komunikuji s klientem MongoDB mongosh a v rámci heredoc jsou předány příkazy bloku kódu pro vytvoření nové databáze, kolekce a přidání vzorového dokumentu.
mongosh << EOF use ostechnix db.data.insertOne({ "Site" : "OsTechnix", "DB" : "Mongo" }) db.data.find().pretty() EOF
Možná znáte MongoDB nebo ne, ale to je v pořádku. Toto je jen pro ukázku, jak používat heredoc k interakci s klienty db. Můžete použít libovolného db klienta, jako je MySQL, psql, sqlite v závislosti na databázi, se kterou pracujete.
Příklad 3:Provádění vzdálených příkazů pomocí HereDoc a SSH
Pokud chcete spouštět příkazy přes vzdálený server, můžete použít heredoc v kombinaci s ssh
příkaz. Normálně pomocí ssh
příkazem, můžete spouštět příkazy na vzdáleném serveru následujícím způsobem.
$ ssh [email protected] "command"
Chcete-li na vzdáleném hostiteli spustit více příkazů, musíte znovu a znovu opakovat stejný příkaz. S heredoc můžete seskupit všechny příkazy a spustit je.
$ ssh -T [email protected] << EOF Command 1... Command 2.. ..... Command N.. EOF
Pokud je třeba provést stejný kód na více uzlech, můžete přidat for loop
spolu s heredocem. Používám stejný fragment pro vytvoření souboru, jaký jsme viděli v prvním příkladu.
- Proměnná pole "server" obsahuje seznam názvů serverů.
- Pro smyčku iteruje přes proměnnou pole.
- Příkaz k vytvoření souboru je předán příkazu SSH, který bude opakovat a vytvářet soubory na každém serveru. Ujistěte se, že jste přidali
-T
flag příkazu ssh, který zakáže alokaci pseudoterminálu.
declare -a server=( host1 host2 host3 ) for host in ${server[@]} do ssh -T [email protected]${host} << EOF echo "Running at host - ${host}" if [[ ! -f /home/ostechnix/test ]];then touch /home/ostechnix/test echo "File Created" else echo "File exists" fi EOF done
Závěr
Heredoc je důležitý koncept pro pochopení a použití ve skriptech Bash. Když napíšete hodně skriptů, dozvíte se více o heredocu a způsobech, jak jej optimálně používat.
Pokud jste heredoc ještě nikdy nepoužili, spusťte terminál a vyzkoušejte všechny úryvky kódu z článku, abyste lépe porozuměli.
Související čtení:
- Bash Scripting – proměnné vysvětlené na příkladech
- Bash Scripting – funkce vysvětlené na příkladech
- Příkaz Bash Echo vysvětlený s příklady v Linuxu
- Bash Scripting – pro smyčku vysvětlenou s příklady
- Bash Scripting – smyčka Zatímco a dokud není vysvětlena příklady