Wanneer je met Bash scripts werkt, kun je in een situatie terechtkomen waarin je een reeks tekstregels moet verwerken met dezelfde opdracht. Gelukkig is er een manier in Bash om dit op een meer optimale manier te doen met HereDoc.
HereDoc, acroniem voor Here Document, is een methode voor het doorgeven van meerdere regels aan een programma of opdracht. Het concept van heredoc is niet alleen gerelateerd aan Bash. Veel populaire programmeertalen zoals Perl, Ruby en PHP ondersteunen heredoc.
opdracht << EOF
Regel 1 Regel 2 ..... Laatste regelEOF
Laten we beginnen met een eenvoudig voorbeeld van het omleiden van een meerregelige tekenreeks en het afdrukken ervan in de terminal.
De opdracht cat
accepteert een invoerstroom en met heredoc kun je het blok met regels omleiden om het op de terminal weer te geven.
dany@pindabook:~$ cat << EOF
> Deze tekst bestaat uit verschillende regels.
> Een gegevenstroom waarop je bewerkingen kunt uitvoeren.
> Dankzij HEREDOC.
> EOF
Deze tekst bestaat uit verschillende regels.
Een gegevenstroom waarop je bewerkingen kunt uitvoeren.
Dankzij HEREDOC.
Bij het intypen verschijnen de >
-tekens automatisch om aan te duiden dat je de opdracht nog verder moet afwerken.
Deze tekens verschijnen niet als je zoals in de volgende voorbeelden oude opdrachten terughaalt met de pijltoetsen omhoog en omlaag.
M.a.w. typ je de opdrachten, dan zie je de >
-tekens, anders niet.
We hebben drie regels die worden doorgestuurd naar de opdracht cat
.
We gebruiken EOF
als scheidingsteken.
Je kunt echter alles gebruiken wat je wilt, maar houd het begin- en eindpunt identiek.
dany@pindabook:~$ wc -l << BLK
Deze tekst bestaat uit verschillende regels.
Een gegevenstroom waarop je bewerkingen kunt uitvoeren.
Dankzij HEREDOC.
BLK
3
Je kunt de uitvoer omleiding operator (>
) combineren met heredoc en de uitvoer omleiden naar een bestand in plaats van het af te drukken in de terminal.
We gebruiken hetzelfde voorbeeld als daarstraks en sturen de uitvoer door naar het bestand met de naam heredoc.txt.
dany@pindabook:~$ cat << EOF > heredoc.txt
Deze tekst bestaat uit verschillende regels.
Een gegevenstroom waarop je bewerkingen kunt uitvoeren.
Dankzij HEREDOC.
EOF
De uitvoer van heredoc kan doorgestuurd (pipe |
) worden voor verdere verwerking.
dany@pindabook:~$ cat << EOF | grep -i HEREDOC
Deze tekst bestaat uit verschillende regels.
Een gegevenstroom waarop je bewerkingen kunt uitvoeren.
Dankzij HEREDOC.
EOF
Dankzij HEREDOC.
Witruimtes zoals spaties worden in heredoc behouden, waardoor je heredoc ook kunt gebruiken om regels te laten inspringen.
dany@pindabook:~$ cat << EOF
Deze tekst bestaat uit verschillende regels.
Een gegevenstroom waarop je bewerkingen kunt uitvoeren.
Dankzij HEREDOC.
EOF
Deze tekst bestaat uit verschillende regels.
Een gegevenstroom waarop je bewerkingen kunt uitvoeren.
Dankzij HEREDOC.
Het is niet zo dat je alleen tekenreeksen kunt doorgeven binnen het HereDoc blok. Je kunt door de gebruiker gedefinieerde variabelen en omgevingsvariabelen doorgeven en opdrachten uitvoeren binnen het blok.
Kijk eens naar het onderstaande voorbeeld.
Binnen het blok, hebben we een door de gebruiker gedefinieerde variabele ${AUTEUR}
, een omgevingsvariabele ${SHELL}
, een externe opdracht whoami
.
Wanneer dit fragment wordt verzonden, worden de variabelen en opdrachten uitgebreid en vervolgens wordt het doorgestuurd naar de cat
opdracht.
dany@pindabook:~$AUTEUR="PindaNet"
dany@pindabook:~$cat << EOF > Auteur: ${AUTEUR} # Zelf gedefinieerde variabele > Tip: Bash Heredoc > Ik gebruik de ${SHELL} terminal # Omgevings variabele > $(whoami) # Uitvoer opdracht > EOF
Auteur: PindaNet # Zelf gedefinieerde variabele Tip: Bash Heredoc Ik gebruik de /bin/bash terminal # Omgevings variabele dany # Uitvoer opdracht
Je kunt de begin delimiter omsluiten met enkele aanhalingstekens om de uitbreiding binnen het blok te onderdrukken. Op deze manier wordt alles binnen het blok behandeld als een letterlijke tekenreeks.
dany@pindabook:~$ cat << 'EOF'
Auteur: ${AUTEUR} # Zelf gedefinieerde variabele
Tip: Bash Heredoc
Ik gebruik de ${SHELL} terminal # Omgevings variabele
$(whoami) # Uitvoer opdracht
EOF
Auteur: ${AUTEUR} # Zelf gedefinieerde variabele
Tip: Bash Heredoc
Ik gebruik de ${SHELL} terminal # Omgevings variabele
$(whoami) # Uitvoer opdracht
Zoals je misschien al weet, ondersteunt Bash geen commentaar van meerdere regels.
Met hereedoc kun je meerregelig commentaar maken door het blok om te leiden naar het no-op opdracht (:
).
De no-op is een in Bash ingebouwde opdracht die de invoer aanneemt en nul teruggeeft.
Je kunt dit zien als een synoniem voor de eveneens in bash ingebouwde true
opdracht die ook nul teruggeeft.
dany@pindabook:~$ : << 'COMMENTAAR'
> Auteur: PindaNet
> Tip: Bash Heredoc
> Bash versie: 5.2.15
> OS: Debian 12 Bookworm
> COMMENTAAR
HereDoc blokken kunnen speciale tekens bevatten. Als je de speciale tekens wilt omzeilen, zijn er een paar manieren om dit voor elkaar te krijgen.
Je kunt het scheidingsteken omsluiten met enkele of dubbele aanhalingstekens of een backslash vooraf laten gaan aan het scheidingsteken. Op deze manier worden alle speciale tekens geëscaped.
dany@pindabook:~$ cat << 'EOF'
Ik gebruik de ${SHELL} terminal # Omgevings variabele
$(whoami) # Uitvoer opdracht
EOF
Ik gebruik de ${SHELL} terminal # Omgevings variabele
$(whoami) # Uitvoer opdracht
dany@pindabook:~$ cat << "EOF"
Ik gebruik de ${SHELL} terminal # Omgevings variabele
$(whoami) # Uitvoer opdracht
EOF
Ik gebruik de ${SHELL} terminal # Omgevings variabele
$(whoami) # Uitvoer opdracht
dany@pindabook:~$ cat << \EOF
Ik gebruik de ${SHELL} terminal # Omgevings variabele
$(whoami) # Uitvoer opdracht
EOF
Ik gebruik de ${SHELL} terminal # Omgevings variabele
$(whoami) # Uitvoer opdracht
In plaats van alle speciale tekens te escapen, kun je ook bepaalde speciale tekens binnen het blok escapen door een backslash toe te voegen voor elk speciaal teken.
dany@pindabook:~$ cat << EOF
Ik gebruik de \${SHELL} terminal # Omgevings variabele
$(whoami) # Uitvoer opdracht
EOF
Ik gebruik de ${SHELL} terminal # Omgevings variabele
dany # Uitvoer opdracht
Als je opdrachten wilt uitvoeren over een SSH verbinding, dan kun je heredoc gebruiken in combinatie met de ssh
opdracht.
Normaal gesproken kun je met de ssh
opdracht op de volgende manier opdrachten uitvoeren op de computer op afstand.
ssh gebruiker@computernaam "opdracht"
Je moet dezelfde opdracht steeds herhalen als je meer opdrachten wilt uitvoeren op afstand. Met heredoc kun je alle opdrachten groeperen en uitvoeren.
dany@main:~$ ssh -T dany@pindabook.local << EOF
> echo -n "Datum: "
> date
> echo -n "Naam: "
> uname -n
> EOF
Linux pindabook 6.1.0-10-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.38-2 (2023-07-27) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Datum: ma 31 jul 2023 13:57:41 CEST
Naam: pindabook
Als dezelfde code op meerdere computers moet worden uitgevoerd, kun je een for-lus toevoegen samen met heredoc. Je kunt dit gebruiken om journal rapporten op verschillende computers op te vragen. In het voorbeeld gebruik ik tweemaal dezelfde computer (pindabook.local).
declare -a server=( pindabook.local pindabook.local ) for host in ${server[@]} do ssh -T dany@${host} << EOF echo "Uitvoeren op - ${host}" journalctl | tail -10 EOF done
Bij het uitvoeren van het bovenstaande script, merken we dat de opdrachten in het HereDoc blok tweemaal via een SSH verbinding op de pindabook.local computer worden uitgevoerd.
dany@main:~$ bash journalall.sh
Linux pindabook 6.1.0-10-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.38-2 (2023-07-27) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Uitvoeren op - pindabook.local
Hint: You are currently not seeing messages from other users and the system.
Users in groups 'adm', 'systemd-journal' can see all messages.
Pass -q to turn off this notice.
jul 31 14:22:47 pindabook wallpaper.sh[1310]: Bereik gemeten omgevingslicht: 1870
jul 31 14:22:47 pindabook wallpaper.sh[1310]: Bereik instelbare helderheid: 468
jul 31 14:22:47 pindabook wallpaper.sh[1310]: Relatief omgevingslicht: 0.04
jul 31 14:22:47 pindabook wallpaper.sh[1310]: Helderheid aanpassen van 108 naar 113
jul 31 14:22:47 pindabook wallpaper.sh[1310]: verhogen: 108
jul 31 14:22:48 pindabook wallpaper.sh[1310]: verhogen: 109
jul 31 14:22:49 pindabook wallpaper.sh[1310]: verhogen: 110
jul 31 14:22:50 pindabook wallpaper.sh[1310]: verhogen: 111
jul 31 14:22:51 pindabook wallpaper.sh[1310]: verhogen: 112
jul 31 14:22:52 pindabook wallpaper.sh[1310]: verhogen: 113
Linux pindabook 6.1.0-10-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.38-2 (2023-07-27) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Uitvoeren op - pindabook.local
Hint: You are currently not seeing messages from other users and the system.
Users in groups 'adm', 'systemd-journal' can see all messages.
Pass -q to turn off this notice.
jul 31 14:22:47 pindabook wallpaper.sh[1310]: Relatief omgevingslicht: 0.04
jul 31 14:22:47 pindabook wallpaper.sh[1310]: Helderheid aanpassen van 108 naar 113
jul 31 14:22:47 pindabook wallpaper.sh[1310]: verhogen: 108
jul 31 14:22:48 pindabook wallpaper.sh[1310]: verhogen: 109
jul 31 14:22:49 pindabook wallpaper.sh[1310]: verhogen: 110
jul 31 14:22:50 pindabook wallpaper.sh[1310]: verhogen: 111
jul 31 14:22:51 pindabook wallpaper.sh[1310]: verhogen: 112
jul 31 14:22:52 pindabook wallpaper.sh[1310]: verhogen: 113
jul 31 14:23:03 pindabook sshd[4158]: Received disconnect from 2a02:a03f:e02a:8901:8254:12a:d1ca:4d3f port 48196:11: disconnected by user
jul 31 14:23:03 pindabook sshd[4158]: Disconnected from user dany 2a02:a03f:e02a:8901:8254:12a:d1ca:4d3f port 48196
Bij de tweede uitvoering zie je een regel in de uitvoer waarbij je ziet dat de vorige verbinding werd verbroken (Disconnected from user dany).