Como usar “Documentos Aqui” no Bash no Linux

Uma janela de terminal em um sistema de computador Linux.
Fatmawati Achmad Zaenuri / Shutterstock

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

Aqui Documentos

Muitos comandos no Linux têm nomes de duas ou três letras. Isso é parcialmente 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 daqueles enigmaticamente curtos. “Aqui, documentos” não são documentos e também não está muito claro a que o “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 geralmente são mais complicados. Em programação e script, “mais complicado” também significa “mais sujeito a bugs” e que seu código é mais difícil de manter.

Onde aqui 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 a partir de um script. Fazer a conexão é fácil, mas uma vez que a conexão foi feita, como você “bombeia” seus comandos de seu script para o shell no computador remoto? Aqui, os documentos permitem que você faça isso de forma muito simples.

Princípios Básicos dos Documentos Aqui

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

COMMAND << limit_string
 .
 .
texto 
dados
variáveis
.
.
limit_string
  • COMANDO : pode ser qualquer comando do Linux que aceite entrada redirecionada. Observe que o echocomando não aceita entrada redirecionada . Se você precisar escrever na tela, pode usar o catcomando, que o faz .
  • << : 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 para o comando. Ele pode conter comandos, texto e variáveis. O conteúdo da lista de dados é alimentado no comando, uma linha de cada vez, até que _limit_string seja encontrado.

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

Recomendado:  Revisão do FastVPN: O que há em um nome?

Isso tornará seus scripts muito mais legíveis se você usar uma string de limite que se refere ao que você está fazendo. Se você estiver enviando uma série de comandos a 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 de sublinhado “ _”. Fazemos isso porque os marca como algo fora do comum em seu script.

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 ” cada vez que pressionar “Enter”. Quando você digita a string de limite “_end_of_text” e clica em “Enter”, a lista de sites é passada para cat,e eles são exibidos na janela do terminal.

cat << _end_of_text 
How-To Geek 
Review Geek 
LifeSavvy 
CloudSavvy IT
MindBounce
_end_of_text

Esse não é o exercício mais interessante, mas demonstra que nada é enviado ao comando até que toda a lista de dados seja agrupada e a string de limite seja encontrada. O catcomando não recebe nenhuma entrada até que você insira a string de 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

cat << "_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

Conforme você segue este artigo, sempre que criar um script, será necessário torná-lo executável antes de ser executado. Em cada caso, use o chmodcomando . Substitua o nome do script em cada exemplo pelo nome do script usado aqui.

chmod + x heredoc-1.sh

Este script contém duas variáveis ​​de ambiente $PWDe $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  sobre o whoamicomando . 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 de limite na primeira linha do documento here entre aspas ” "“, a lista de dados é passada para o comando here document literalmente. Os nomes das variáveis ​​são exibidos em vez dos valores das variáveis ​​e a substituição do comando não ocorrerá.

#! / bin / bash

cat << - "_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

Tratamento de caracteres de tabulação

Por padrão, os caracteres da guia 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 chmodcomando. Edite as linhas recuadas para se certificar de que têm um ou dois caracteres de tabulação no início da linha, em vez de uma série de espaços.

#! / bin / bash

cat << _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.

Recomendado:  Como corrigir o erro “Driver de kernel não instalado (rc = -1908)” do VirtualBox em um Mac

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

cat << - _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 iniciais devido às seções recuadas dos scripts.

Loops e outras construções lógicas são geralmente recuadas. 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 guia inicial.
  Linha 2 com uma guia inicial.
  Linha 3 com uma guia 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 >” (crie o arquivo) ou “ >>” (crie o arquivo se ele não existir, anexe 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 “sessão.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
cat session.text

Canalizando a saída para outro comando

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

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

#! / bin / bash

cat << _end_of_text | sed 's / a / e / g'
Como
Para
Gaak
_end_of_text
./heredoc-5.sh

“Gaak” foi corrigido para “Geek”.

Envio de 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 ()
{
leia make
ler modelo
leia new_used
leia delivery_collect
ler localização
ler preço
}

# O documento aqui que passa os dados para set_car_details ()
set_car_details << _mars_rover_data
NASA
Perseverance Rover
Usado
Colete
Marte (longo, lat) 77.451865,18.445161
2,2 bilhões
_mars_rover_data

# Recupere os detalhes do veículo
echo "Make: $ make"
echo "Model: $ model"
echo "Novo ou usado: $ new_used"
echo "Entrega ou coleta: $ delivery_collect"
echo "Localização: $ location"
echo "Preço \ $: $ preço"
./heredoc-6.sh

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

Recomendado:  Como permitir pop-ups no Safari no Mac

Criação e envio de e-mail

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

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

#! / bin / bash

artigo = "Aqui Documentos"

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

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 Documentos Aqui com SSH

Aqui, os documentos são uma maneira poderosa e conveniente de executar alguns comandos em um computador remoto, uma vez que uma conexão SSH tenha sido estabelecida. Se você configurou as 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 “remote-pc”. A conta do usuário é chamada de “dave”. Estamos usando a -Topção (desabilitar alocação de pseudoterminal) porque não precisamos que um pseudoterminal 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ê pode 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 – fará é atualizar um log de conexão no computador remoto. A conta do usuário e um carimbo de hora e data são registrados em um arquivo de texto.

#! / bin / bash

ssh -T dave@remote-pc.local << _remote_commands

# faça algum trabalho aqui

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

Quando executamos o comando, é solicitada a senha da conta no computador remoto .

./heredoc-8.sh

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

No computador remoto , podemos usar catpara verificar o registro de conexão:

cat conn_log / script.log

Cada conexão é listada para nós.

Nome estranho, características interessantes

Aqui, os documentos são peculiares, mas poderosos, especialmente quando usados ​​para enviar comandos a um computador remoto. Seria 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 diminuindo.