Kako koristiti Heredoc u shell skriptiranju


Ovdje dokument (Heredoc) je literal ulaza ili toka datoteke koji se tretira kao poseban blok koda. Ovaj blok koda će biti proslijeđen naredbi za obradu. Heredoc potječe od UNIX školjki i može se naći u popularnim Linux školjkama kao što su sh, tcsh, ksh, bash, zsh, csh. Značajno je da drugi programski jezici kao što su Perl, Ruby, PHP takođe podržavaju heredoc.

Struktura Herdoc

Heredoc koristi 2 ugaone zagrade (<<) nakon kojih slijedi oznaka za razdvajanje. Isti token za razgraničenje će se koristiti za završetak bloka koda. Sve što se nalazi unutar graničnika smatra se blokom koda.

Pogledajte primjer ispod. Preusmjeravam blok koda na naredbu cat. Ovdje je graničnik postavljen na “BLOCK” i završava istim “BLOCK”.

cat << BLOCK
	Hello world
	Today date is $(date +%F)
	My home directory = ${HOME}
BLOCK

NAPOMENA: Trebali biste koristiti isti graničnik za početak bloka i završetak bloka.

Kreirajte višelinijske komentare

Ako trenutno kodirate u bash-u, možda znate da bash prema zadanim postavkama ne podržava višelinijske komentare kao što su C ili Java. Možete koristiti HereDoc da ovo prevaziđete.

Ovo nije ugrađena karakteristika bash-a koji podržava komentare u više redova, već samo hak. Ako ne preusmjeravate heredoc na bilo koju komandu, tumač će jednostavno pročitati blok koda i neće izvršiti ništa.

<< COMMENT
	This is comment line 1
	This is comment line 2
	This is comment line 3
COMMENT

Rukovanje bijelim prostorima

Prema zadanim postavkama, heredoc neće potisnuti razmake (tabulatore, razmake). Ovo ponašanje možemo nadjačati dodavanjem crtice (-) iza (<<) nakon čega slijedi graničnik. Ovo će potisnuti sve razmake na kartici, ali bijeli prostori neće biti potisnuti.

cat <<- BLOCK
This line has no whitespace.
  This line has 2 white spaces at the beginning.
    This line has a single tab.
        This line has 2 tabs.
            This line has 3 tabs.
BLOCK

Varijabla i zamjena komandi

Heredoc prihvata promenljivu supstituciju. Varijable mogu biti korisnički definirane varijable ili varijable okruženja.

TODAY=$(date +%F)
	
cat << BLOCK1
User defined variables
Today date is = ${TODAY}
#Environ Variables
I am running as = ${USER}
My home dir is = ${HOME}
I am using ${SHELL} as my shell
BLOCK1

Slično, možete pokrenuti bilo koju komandu unutar heredoc kodnog bloka.

cat << BLOCK2
$(uname -a) 
BLOCK2

Izbjegavanje posebnih znakova

Postoji nekoliko načina na koje možemo izbjeći posebne znakove. Ili to možete učiniti na nivou karaktera ili na nivou dokumenta.

Za izbjegavanje pojedinačnih posebnih znakova koristite obrnutu kosu crtu (\).

cat << BLOCK4
$(uname -a)
BLOCK4

cat << BLOCK5
Today date is = ${TODAY}
BLOCK5

Da biste izbjegli sve specijalne znakove unutar bloka, okružite graničnik jednostrukim navodnicima, dvostrukim navodnicima ili prefiks graničnik s obrnutom kosom crtom.

cat << 'BLOCK1'
I am running as = ${USER}
BLOCK1

cat << "BLOCK2"
I am running as = ${USER}
BLOCK2

cat << \BLOCK3
I am running as = ${USER}
BLOCK3

Sada kada znamo strukturu heredoca i kako ona funkcionira, pogledajmo nekoliko primjera. Dvije uobičajene oblasti u kojima koristim heredoc su pokretanje bloka komandi preko SSH-a i prosljeđivanje SQL upita kroz heredoc.

U primjeru ispod, pokušavamo izvršiti blok koda na udaljenom serveru preko SSH-a.

U donjem primjeru prosljeđujem select naredbu psql da se povežem na bazu podataka i pokrenem upit. Ovo je alternativni način za pokretanje upita u psql unutar bash skripte umjesto korištenja oznake -f za pokretanje datoteke .sql.

#!/usr/bin/env bash

UNAME=postgres
DBNAME=testing

psql --username=${UNAME} --password --dbname=${DBNAME} << BLOCK
SELECT * FROM COUNTRIES
WHERE region_id = 4;
BLOCK

To je to za ovaj članak. Postoji mnogo više što možete učiniti sa heredoc u poređenju sa onim što smo pokazali u primjerima. Ako imate bilo kakav koristan hak sa heredoc, objavite ga u odjeljku za komentare kako bi naši čitaoci mogli imati koristi od toga.