Skrypty powłoki Bash #15 - Tu Dokument ten mnie daj
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ą doCOMMAND
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.