Wstęp

Dzień dobry, dziś przedstawię kilka informacji na temat HereDoc i HereString. Serdecznie zapraszam.

Co to są heredoc i herestring?

Heredoc jest to specjalny blok kodu, tekstu lub obu. Zawierający treść w wielu liniach, która może zostać przekierowana na wejście komendy.

Herestring, jest to łańcuch znaków, który jest wprowadzany bezpośrednio na wejście komendy. Taki heredoc, ale jedno linijkowy.

Heredoc

Składnia

Do korzystania z heredoc potrzebujemy znaków przekierowania << oraz następującego słowa klucza, który będzie oznaczał koniec dokumentu. Słowo te może być dowolne. Ja posłużę się słowem EOD (skrót od End Of Document).

Przykład:

cat <<EOD
line 1
line 2
line 3
EOD

Usuwanie białych znaków

Domyślnie heredoc bierze treść “as is” czyli tak jak ją wprowadzamy. Może się zdarzyć tak, że kopiujemy jakiś kod z indentacją (tylko tabulacje). Wtedy, do wyczyszczenia niechcianych odstępów, posłuży się nam znak -, który usunie nam indentacje z naszego tekstu. Wstawiamy go między << a token(słowo klucz).

A cały dokument może wyglądać tak:

cat <<-EOD
line ok 
		lite tab
  line 2 spaces
EOD

W samym terminalu może być problem z uzyskaniem tabulacji. Dodatkowo podczas pisania tego artykułu pożądany efekt uzyskałem, dopiero korzystając z terminala w środowisku graficznym. O dziwo ssh poprzez putty, pwsh czy alacritty (openssh) nie przynosiły porządanego efektu. Choć przy mojej pracy na HP-UX działało ¯\_(ツ)_/¯

Z tym zapisem najprawdopodobniej spotkamy się najczęściej w skryptach i vim’ie

Podstawianie wartości w Heredoc

Możemy w Heredocu korzystać ze zmiennych, by uczynić je “dynamicznymi”

Powiedzmy, że piszemy w Heredocu kilka komend i chcemy, by przekształciły się w komendy dla konkretnego użytkownika, wtedy piszemy:

cat <<EOD
mkdir /home/${USER}/tmp
mv /opt/program/tmp /home/${USER}/tmp
source /home/${USER}/tmp/env
/home/${USER}/tmp/app.bin
EOD

W wyniku otrzymamy komendy sparametryzowane pod użytkownika:

mkdir /home/mlewicki/tmp
mv /opt/program/tmp /home/mlewicki/tmp
source /home/mlewicki/tmp/env
/home/mlewicki/tmp/app.bin

Podstawianie komend w Heredoc

Możemy również, w Heredoc, umieścić wyniki komend. Dla przykładu, chcemy wyświetlić godzinę oraz zawartość katalogu użytkownika. Wtedy zapiszemy to tak:

cat <<EOD
Jest obecnie : $(date)
### ZAWARTOŚĆ ~/ ###
$(ls ~/)
EOD

Wynik będzie przykładowo taki:

Jest obecnie : Fri Sep 24 19:57:09 CEST 2021
### ZAWARTOŚĆ ~/ ###
tst.txt

Przekazywanie argumentów przy pomocy heredoc

Co może niektórych z was zaciekawić. Możemy poprzez heredoc przekazać argumenty do funkcji. No właściwie przekazać wartości do komend wczytania.

Załóżmy, że mamy taką funkcję:

wczytaj2(){
	read -p "Użyszkodnik: " user
	read -p "Hasełko: " pass
	echo "Pojawił się nowy człek ${user} jego hasełko to ${pass} zapisz sobie"
}

Jeśli wywołalibyśmy komendę normalnie, to zapytała, by się nas o wartości dla zmiennes user i pass :

[mlewicki@lxorasrv1 ~]$ wczytaj2
Użyszkodnik: marian
Hasełko: cyganka12
Pojawił się nowy człek marian jego hasełko to cyganka12 zapisz sobie

Możemy, zamiast wpisywać wartości z “palca”, użyć heredoc’a:

wczytaj2 <<EOD
marian
cyganka12
EOD

Wynik będzie taki sam:

[mlewicki@lxorasrv1 ~]$ wczytaj2 <<EOD
marian
cyganka12
EOD
Pojawił się nowy człek marian jego hasełko to cyganka12 zapisz sobie

Znaki ucieczki

Domyślnie znaki specjalne jak $, \, i ` są interpretowane jak w skryptach, aby funkcjonalność podstawiania mogła działać. Jeżeli chcemy użyć znaku specjalnego jako literału, to musimy go poprzedzić znakiem \

cat <<EOD
znaki specjalne: \$ \\ \`
EOD

Jeżeli chcemy by każdy znak, jaki wprowadzimy, był zwykłym znakiem i nie był interpretowany przez powłokę specjalnie, możemy umieścić token w cudzysłowie, apostrofach lub poprzedzić znakiem \.

Trzy sposoby na “zwykły tekst”:

cat <<'EOF'
Some Special Characters: $ \ `
EOF
cat <<"EOF"
Some Special Characters: $ \ `
EOF
cat <<\EOF
Some Special Characters: $ \ `
EOF

Proszę pamiętać, że po wyeliminowaniu interpretowania znaków specjalnych, znika możliwość podstawiania komend i zmiennych.

“Komentarz” wieloliniowy

W skryptach bashowych możemy wykorzystać heredoc jako komentarz wieloliniowy.

Wystarczy, że zaczniemy od linii: <<'TOKEN'

gdzie: : jest funkcją wbudowaną a 'TOKEN' musi być w cudzysłowie, inaczej kod się wykona!

#!/bin/bash

: <<'DISABLED'
echo "Nie działa 1"
echo "Nie działa 2"
DISABLED

echo "Działa"

Here String

Herestring jest, powiedzmy “kuzynem” Heredoc’a. Jest on prostszy, nie potrzebuje “tokena” oraz zwykle jest on krótki.

Budowa

Do stworzenia Herestring wykorzystujemy operator <<<, który przekazuje string bezpośrednio do komendy.

zapis:

COMMAND <<< "Jakiś tekst"
COMMAND <<< $VAR

Drugi przykład rozwiązuje zmienną $VAR i przekazuje ją do COMMAND jako string/łańcuch znaków.

String w miejscu z parametrem

Tak samo jak w Heredoc’u. Herestring może podstawiać zmienne:

cat <<< "Witaj! ${USER}"

Znaki specjalne w HereString

By zatrzymać interpretowanie znaków specjalnych, zamykamy string w apostrofy '

cat <<< 'Display special characters: $ ` \'

Epilog

Na dziś wystarczy, mam nadzieję, że dowiedziałeś/łaś się czegoś nowego, albo odświeżyłeś/łaś sobie wiedzę. Tak czy inaczej, serdecznie Ci dziękuję, za przeczytanie tego posta. Jeśli masz potrzebę o cos zapytać, kontakt znajdziesz w zakładce “O Mnie”. A teraz życzę miłego dzionka i smacznej kawusi :) Do widzenia.