Como usar Heredoc em scripts Shell
Aqui, documento (Heredoc) é uma entrada ou fluxo de arquivo literal que é tratado como um bloco especial de código. Este bloco de código será passado para um comando para processamento. Heredoc se origina em shells UNIX e pode ser encontrado em shells Linux populares como sh, tcsh, ksh, bash, zsh, csh. Notavelmente, outras linguagens de programação como Perl, Ruby, PHP também suportam heredoc.
Estrutura de Herdoque
Heredoc usa 2 colchetes angulares (<<)
seguidos por um token delimitador. O mesmo token delimitador será usado para encerrar o bloco de código. Tudo o que estiver dentro do delimitador é considerado um bloco de código.
Veja o exemplo abaixo. Estou redirecionando o bloco de código para o comando cat. Aqui o delimitador é definido como “BLOCK” e termina com o mesmo “BLOCK“.
cat << BLOCK
Hello world
Today date is $(date +%F)
My home directory = ${HOME}
BLOCK
NOTA: Você deve usar o mesmo token delimitador para iniciar e encerrar o bloco.
Crie comentários multilinhas
Se você estiver codificando em bash agora, você deve saber que o bash por padrão não suporta comentários multilinhas como C ou Java. Você pode usar o HereDoc para superar isso.
Este não é um recurso interno do bash que suporta comentários multilinhas, mas apenas um hack. Se você não estiver redirecionando o heredoc para nenhum comando, o interpretador simplesmente lerá o bloco de código e não executará nada.
<< COMMENT
This is comment line 1
This is comment line 2
This is comment line 3
COMMENT
Lidando com espaços em branco
Por padrão, heredoc não suprimirá nenhum caractere de espaço em branco (tabulações, espaços). Podemos substituir esse comportamento adicionando traço (-)
após (<<)
seguido por um delimitador. Isso suprimirá todos os espaços de tabulação, mas os espaços em branco não serão suprimidos.
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
Substituição de variáveis e comandos
Heredoc aceita substituição de variáveis. As variáveis podem ser variáveis definidas pelo usuário ou variáveis ambientais.
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
Da mesma forma, você pode executar qualquer comando dentro do bloco de código heredoc.
cat << BLOCK2
$(uname -a)
BLOCK2
Escapando de caracteres especiais
Existem várias maneiras de escapar de caracteres especiais. Você pode fazer isso no nível do personagem ou no nível do documento.
Para escapar de caracteres especiais individuais, use uma barra invertida (\).
cat << BLOCK4
$(uname -a)
BLOCK4
cat << BLOCK5
Today date is = ${TODAY}
BLOCK5
Para escapar de todos os caracteres especiais dentro do bloco, coloque o delimitador entre aspas simples, aspas duplas ou o delimitador de prefixo com uma barra invertida.
cat << 'BLOCK1'
I am running as = ${USER}
BLOCK1
cat << "BLOCK2"
I am running as = ${USER}
BLOCK2
cat << \BLOCK3
I am running as = ${USER}
BLOCK3
Agora que conhecemos a estrutura do heredoc e como ele funciona, vamos ver alguns exemplos. Duas áreas comuns onde uso heredoc são executar um bloco de comandos por SSH e passar consultas SQL por meio de heredoc.
No exemplo abaixo, estamos tentando executar um bloco de código em um servidor remoto através de SSH.
No exemplo abaixo estou passando uma instrução select para psql para conectar-se a um banco de dados e executar a consulta. Esta é uma maneira alternativa de executar uma consulta no psql dentro do script bash em vez de usar o sinalizador -f
para executar o arquivo .sql.
#!/usr/bin/env bash
UNAME=postgres
DBNAME=testing
psql --username=${UNAME} --password --dbname=${DBNAME} << BLOCK
SELECT * FROM COUNTRIES
WHERE region_id = 4;
BLOCK
É isso neste artigo. Há muito mais que você pode fazer com o heredoc em comparação com o que mostramos nos exemplos. Se você tiver algum truque útil com heredoc, poste-o na seção de comentários para que nossos leitores possam se beneficiar com isso.