Como usar “Here Documents” no Bash no Linux

Publicados: 2022-01-29
Uma janela de terminal em um sistema de computador Linux.
Fatmawati Achmad Zaenuri/Shutterstock

Os estranhos “documentos aqui” permitem que você use o redirecionamento de entrada/saída dentro de scripts Bash no Linux. Eles são uma ótima maneira de automatizar comandos que você precisa executar em um computador remoto.

Aqui Documentos

Muitos comandos no Linux têm nomes de duas ou três letras. Isso é em parte o que dá origem à noção de que o Linux é difícil de aprender e cheio de comandos misteriosos. Mas um dos nomes mais estranhos no Linux não é um dos cripticamente curtos. “Documentos aqui” não são documentos, e também não está muito claro a que “aqui” se refere.

Eles são uma construção relativamente obscura, mas são úteis. Claro, isso é Linux, então há mais de uma maneira de esfolar um gato. Algumas das funcionalidades fornecidas por estes documentos podem ser reproduzidas de outras maneiras. Esses métodos alternativos são geralmente mais complicados. Em programação e script, “mais complicado” também significa “mais propenso a bugs” e que seu código é mais difícil de manter.

Onde os documentos realmente se destacam é na automação de comandos que você deseja enviar para um computador remoto a partir de uma conexão estabelecida de dentro de um script. Fazer a conexão é fácil, mas uma vez que a conexão foi feita, como você “bombe” seus comandos do seu script para o shell do computador remoto? Aqui os documentos permitem que você faça isso de maneira muito simples.

Princípios Básicos dos Documentos Aqui

A representação idiomática de um documento here é assim:

 COMANDO << limit_string
 .
 .
texto 
dados
variáveis
.
.
limit_string
  • COMMAND : Pode ser qualquer comando do Linux que aceite entrada redirecionada. Observe que o comando echo não aceita entrada redirecionada. Se você precisar escrever na tela, poderá usar o comando cat , que funciona.
  • << : O operador de redirecionamento.
  • limit_string : Este é um rótulo. Pode ser o que você quiser, desde que não apareça na lista de dados que você está redirecionando para o comando. É usado para marcar o final da lista de texto, dados e variáveis.
  • Lista de dados : Uma lista de dados a serem alimentados ao comando. Ele pode conter comandos, texto e variáveis. O conteúdo da lista de dados é inserido no comando uma linha de cada vez até que a _limit_string seja encontrada.
Propaganda

Você provavelmente verá exemplos de documentos aqui que usam “EOF” como a string limite. Não favorecemos essa abordagem. Funciona, mas “EOF” significa “Fim do arquivo”. Além do raro caso em que um documento inicial é a última coisa em um arquivo de script, “EOF” está sendo usado erroneamente.

Isso tornará seus scripts muito mais legíveis se você usar uma string de limite que se refira ao que você está fazendo. Se você estiver enviando uma série de comandos para um computador remoto por Secure Shell (SSH), uma string de limite chamada algo como “_remote_commands” faria todo o sentido. Você não precisa iniciá-los com um caractere sublinhado “ _ ”. Fazemos isso porque os marca como algo fora do comum em seu roteiro.

Exemplos simples

Você pode usar aqui documentos na linha de comando e em scripts. Ao digitar o seguinte em uma janela de terminal, você verá um prompt de continuação de linha “ > ” toda vez que pressionar “Enter”. Quando você digita a string de limite “_end_of_text” e pressiona “Enter”, a lista de sites é passada para cat, e eles são exibidos na janela do terminal.

 gato << _end_of_text 
Geek de instruções 
Crítica Geek 
LifeSavvy 
TI CloudSavvy
MindBounce
_end_of_text 

Esse não é o exercício mais valioso, mas demonstra que nada é enviado ao comando até que toda a lista de dados seja coletada e a string limite seja encontrada. O comando cat não recebe nenhuma entrada até que você insira a string limite “_end_of_text” e pressione a tecla “Enter”.

Podemos fazer a mesma coisa em um script. Digite ou copie este exemplo em um editor, salve o arquivo como “heredoc-1.sh” e feche o editor.

 #!/bin/bash

gato << "_end_of_texto"
Seu nome de usuário é: $(whoami)
Seu diretório de trabalho atual é: $PWD
Sua versão do Bash é: $BASH_VERSION
_end_of_text

Ao seguir este artigo, cada vez que criar um script, você precisará torná-lo executável antes de executá-lo. Em cada caso, use o comando chmod . Substitua o nome do script em cada exemplo pelo nome do script usado aqui.

 chmod +x heredoc-1.sh 

Propaganda

Este script contém duas variáveis ​​de ambiente, $PWD e $BASH_VERSION . Os nomes das variáveis ​​de ambiente são substituídos por seus valores de dados - o diretório de trabalho atual e a versão do Bash - quando o script é executado.

O script também usa substituição de comando no comando whoami . O nome do comando é substituído por sua própria saída. A saída de todo o script é gravada na janela do terminal pelo comando cat. Executamos o script chamando-o pelo nome:

 ./heredoc-1.sh 

Se você modificar o script e colocar a string limite na primeira linha do documento here entre aspas ” " “, a lista de dados será passada para o comando do documento here na íntegra. não ocorra.

 #!/bin/bash

gato <<- "_end_of_text"
Seu nome de usuário é: $(whoami)
Seu diretório de trabalho atual é: $PWD
Sua versão do Bash é: $BASH_VERSION
_end_of_text
 ./heredoc-1.sh 

Manipulando Caracteres de Tabulação

Por padrão, os caracteres de tabulação em sua lista de dados serão retidos e gravados na janela do terminal. Copie e salve este exemplo como “heredoc-2.sh”. Torne-o executável usando o comando chmod . Edite as linhas recuadas para garantir que elas tenham um ou dois caracteres de tabulação no início da linha, em vez de uma série de espaços.

 #!/bin/bash

gato << _end_of_text
Seu nome de usuário é: $(whoami)
  Seu diretório de trabalho atual é: $PWD
    Sua versão do Bash é: $BASH_VERSION
_end_of_text
 ./heredoc-2.sh 

As guias são gravadas na janela do terminal.

Ao adicionar um traço “ - ” ao operador de redirecionamento, o documento here irá ignorar os caracteres de tabulação à esquerda. Salve este exemplo como “heredoc-3.sh” e torne-o executável.

 #!/bin/bash

gato <<- _end_of_text
Seu nome de usuário é: $(whoami)
  Seu diretório de trabalho atual é: $PWD
    Sua versão do Bash é: $BASH_VERSION
_end_of_text
 ./heredoc-3.sh 

As guias são ignoradas. Isso pode parecer trivial, mas é uma maneira legal de lidar com as guias principais devido às seções recuadas dos scripts.

Propaganda

Loops e outras construções lógicas geralmente são recuados. Se o seu documento here estiver contido em uma seção recuada de um script, usar um traço “ - ” com o operador de redirecionamento remove os problemas de formatação causados ​​pelos caracteres de tabulação à esquerda.

 #!/bin/bash

se for verdade; então
  gato <<- _limit_string
  Linha 1 com uma tabulação inicial.
  Linha 2 com uma tabulação inicial.
  Linha 3 com uma tabulação inicial.
  _limit_string
fi

Redirecionando para um arquivo

A saída do comando usado com o documento here pode ser redirecionada para um arquivo. Use os operadores de redirecionamento “ > ” (criar o arquivo) ou “ >> ” (criar o arquivo se ele não existir, anexar ao arquivo se existir) após a string de limite na primeira linha do documento aqui.

Este script é “heredoc-4.sh”. Ele redirecionará sua saída para um arquivo de texto chamado “session.txt”.

 #!/bin/bash

cat << _end_of_text > session.txt
Seu nome de usuário é: $(whoami)
Seu diretório de trabalho atual é: $PWD
Sua versão do Bash é: $BASH_VERSION
_end_of_text
 ./heredoc-4.sh
 sessão de gato.texto 

Encaminhando a saída para outro comando

A saída do comando usado em um documento here pode ser canalizada como entrada para outro comando. Use o tubo “ |após a string de limite na primeira linha do documento aqui. Vamos canalizar a saída do comando here document, cat , para sed . Queremos substituir todas as ocorrências da letra “a” pela letra “e”.

Nomeie este script como “heredoc-5.sh”.

 #!/bin/bash

gato << _end_of_text | sed 's/a/e/g'
Quão
Para
Gaak
_end_of_text
 ./heredoc-5.sh

"Gaak" é corrigido para "Geek".

Enviando Parâmetros para uma Função

O comando usado com um documento here pode ser uma função no script.

Este script passa alguns dados do veículo para uma função. A função lê os dados como se tivessem sido digitados por um usuário. Os valores das variáveis ​​são então impressos. Salve este script como “heredoc-6.sh”.

 #!/bin/bash

# a função set_car_details()
set_car_details ()
{
ler fazer
leia o modelo
leia novo_usado
leia delivery_collect
leia a localização
leia o preço
}

# O documento here que passa os dados para set_car_details()
set_car_details << _mars_rover_data
NASA
Rover Perseverança
Usava
Coletar
Marte (longo, lat) 77.451865,18.445161
2,2 bilhões
_mars_rover_data

# Recuperar os detalhes do veículo
echo "Fazer: $fazer"
echo "Modelo: $modelo"
echo "Novo ou usado: $new_used"
echo "Entrega ou Coleta: $delivery_collect"
echo "Localização: $localização"
echo "Preço \$: $preço"
 ./heredoc-6.sh 

Os detalhes do veículo são gravados na janela do terminal.

Criando e enviando um e-mail

Podemos usar um documento aqui para compor e enviar um e-mail. Observe que podemos passar parâmetros para o comando na frente do operador de redirecionamento. Estamos usando o comando Linux mail para enviar um e-mail através do sistema de correio local para a conta de usuário chamada “dave”. A opção -s (assunto) nos permite especificar o assunto do email.

Este exemplo forma o script “heredoc-7.sh”.

 #!/bin/bash

article="Aqui Documentos"

mail -s 'Status da carga de trabalho' dave << _project_report
Nome de usuário: $(whoami)
Completou a tarefa:
Artigo: $artigo
_relatório de Projeto
 ./heredoc-7.sh 

Propaganda

Não há saída visível deste script. Mas quando verificamos nosso e-mail, vemos que o e-mail foi composto, despachado e entregue.

 correspondência 

Usando aqui documentos com SSH

Aqui, os documentos são uma maneira poderosa e conveniente de executar alguns comandos em um computador remoto assim que uma conexão SSH for estabelecida. Se você configurou chaves SSH entre os dois computadores, o processo de login será totalmente automático. Neste exemplo rápido e sujo, você será solicitado a fornecer a senha da conta de usuário no computador remoto.

Este script é “heredoc-8.sh”. Vamos nos conectar a um computador remoto chamado “pc remoto”. A conta de usuário é chamada de "dave". Estamos usando a opção -T (desativar alocação de pseudo-terminal) porque não precisamos que um pseudo-terminal interativo seja atribuído a nós.

Na seção “faça algum trabalho aqui” do script, poderíamos passar uma lista de comandos, e estes seriam executados no computador remoto. Claro, você poderia simplesmente chamar um script que estava no computador remoto. O script remoto pode conter todos os comandos e rotinas que você deseja executar.

Tudo o que nosso script—heredoc-8.sh—vai fazer é atualizar um log de conexão no computador remoto. A conta de usuário e um carimbo de data e hora são registrados em um arquivo de texto.

 #!/bin/bash

ssh -T [email protected] << _remote_commands

#faça um trabalho aqui

# atualiza o log de conexão
echo $USER "-" $(data) >> /home/dave/conn_log/script.log
_remote_commands
Propaganda

Quando executamos o comando, somos solicitados a fornecer a senha da conta no computador remoto .

 ./heredoc-8.sh 

Algumas informações sobre o computador remoto são exibidas e retornamos ao prompt de comando.

No computador remoto , podemos usar cat para verificar o log de conexão:

 cat conn_log/script.log 

Cada conexão é listada para nós.

RELACIONADO: Como criar e instalar chaves SSH do shell do Linux

Nome estranho, recursos legais

Aqui os documentos são peculiares, mas poderosos, especialmente quando usados ​​para enviar comandos para um computador remoto. Seria uma questão simples criar um script de rotina de backup usando rsync . O script pode então se conectar ao computador remoto, verificar o espaço de armazenamento restante e enviar um e-mail de alerta se o espaço estiver acabando.

RELACIONADO: Como fazer backup do seu sistema Linux com rsync