Slik bruker du Heredoc i Shell-skripting


Her er dokument (Heredoc) en inndata- eller filstrøm bokstavelig som behandles som en spesiell kodeblokk. Denne kodeblokken vil bli sendt til en kommando for behandling. Heredoc har sin opprinnelse i UNIX-skall og kan finnes i populære Linux-skall som sh, tcsh, ksh, bash, zsh, csh. Spesielt andre programmeringsspråk som Perl, Ruby, PHP støtter også heredoc.

Strukturen til Herdoc

Heredoc bruker to vinkelparenteser (<<) etterfulgt av et skilletegn. Det samme skilletegn vil bli brukt for å avslutte kodeblokken. Det som kommer innenfor skilletegnet anses å være en kodeblokk.

Se på eksemplet nedenfor. Jeg omdirigerer kodeblokken til cat-kommandoen. Her er skilletegnet satt til «BLOKK» og avsluttet av samme «BLOKK».

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

MERK: Du bør bruke samme skilletegn for å starte blokkeringen og avslutte blokkeringen.

Lag flerlinjekommentarer

Hvis du koder en gang i bash nå, vet du kanskje at bash som standard ikke støtter flerlinjekommentarer som C eller Java. Du kan bruke HereDoc for å overvinne dette.

Dette er ikke en innebygd funksjon i bash som støtter flerlinjekommentarer, men bare et hack. Hvis du ikke omdirigerer heredoc til noen kommando, vil tolken ganske enkelt lese kodeblokken og vil ikke utføre noe.

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

Håndtering av hvite mellomrom

Som standard vil ikke heredoc undertrykke noen mellomromstegn (tabs, mellomrom). Vi kan overstyre denne oppførselen ved å legge til bindestrek (-) etter (<<) etterfulgt av et skilletegn. Dette vil undertrykke alle tabulatorrom, men hvite mellomrom vil ikke bli undertrykt.

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

Variabel og kommandoerstatning

Heredoc aksepterer variabel substitusjon. Variabler kan være brukerdefinerte variabler eller miljøvariabler.

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

På samme måte kan du kjøre alle kommandoer i heredoc-kodeblokken.

cat << BLOCK2
$(uname -a) 
BLOCK2

Rømmende spesialtegn

Det er flere måter vi kan unnslippe spesialtegn. Enten kan du gjøre det på tegnnivå eller dokumentnivå.

For å unnslippe individuelle spesialtegn, bruk en omvendt skråstrek (\).

cat << BLOCK4
$(uname -a)
BLOCK4

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

For å unnslippe alle spesialtegn inne i blokken, omslutt skilletegnet med enkle anførselstegn, doble anførselstegn eller prefiksskilletegn med omvendt skråstrek.

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

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

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

Nå som vi kjenner strukturen til heredoc og hvordan den fungerer, la oss se noen eksempler. To vanlige områder hvor jeg bruker heredoc er å kjøre en blokk med kommandoer over SSH og sende SQL-spørringer gjennom heredoc.

I eksemplet nedenfor prøver vi å kjøre en kodeblokk på en ekstern server gjennom SSH.

I eksemplet nedenfor sender jeg en select-setning til psql for å koble til en database og kjøre spørringen. Dette er en alternativ måte å kjøre en spørring i psql inne i bash-skriptet i stedet for å bruke -f-flagget for å kjøre .sql-filen.

#!/usr/bin/env bash

UNAME=postgres
DBNAME=testing

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

Det er det for denne artikkelen. Det er mye mer du kan gjøre med heredoc sammenlignet med det vi har vist i eksemplene. Hvis du har noe nyttig hack med heredoc, vennligst legg det ut i kommentarfeltet slik at leserne våre kan dra nytte av det.