Pesquisa de site

Como automatizar comandos CLI interativos com expect


Expect é um utilitário gratuito e de código aberto que podemos usar para responder automaticamente a prompts interativos de acordo com scripts que incluem comandos expect/sends. Neste tutorial, aprendemos como instalar o expect nas distribuições Linux mais usadas, como usá-lo para responder automaticamente a prompts interativos e como gerar scripts expect com autoexpect.

Neste tutorial você aprenderá:

  • Como instalar o expect na distribuição Linux mais usada
  • Como escrever um script esperado
  • Como usar o autoexpect para gerar scripts esperados automaticamente

Instalando espera

Embora expect esteja disponível nos repositórios de todas as principais distribuições Linux, geralmente não é instalado por padrão. Para instalar o utilitário no Fedora e outras distribuições da família Red Hat, como Rocky Linux, podemos usar o gerenciador de pacotes dnf:

$ sudo dnf install expect

Para instalar o pacote no Debian ou outras distribuições baseadas nele, podemos executar:

$ sudo apt-get update && sudo apt-get install expect

Expect também está disponível no repositório “Extra” do Archlinux. Podemos instalar usando pacman:

$ sudo pacman -Sy expect

Espere exemplo de uso

Certos utilitários e programas de linha de comando, além de poderem trabalhar de forma interativa, permitem ao usuário passar os argumentos necessários por meio de opções dedicadas. Em outros casos, por vários motivos, eles não têm essas opções: é aí que expect se torna útil.

Ao criar scripts expect dedicados, podemos automatizar a execução de comandos que requerem interação do usuário, fornecendo respostas predefinidas aos prompts esperados. Vejamos alguns exemplos básicos. Aqui criamos um script que faz algumas perguntas (nome, país e endereço de e-mail):

#!/bin/bash 
read -p "What is your name? " name 
read -p "What is your country? " country 
read -p "Enter your email address: " email

O script é trivial, não realiza nenhuma validação de dados, mas é suficiente para o nosso propósito. Nós o salvamos como “prompts.sh” e damos a ele permissões executáveis:

$ chmod +x prompts.sh

Assim que o executarmos, conforme esperado, ele nos solicitará as informações solicitadas:

$ ./prompts.sh
What is your name? Egidio
What is your country? Italy
Enter your email address: nomail@gmail.com

Assim que respondermos ao primeiro prompt criado pelo script e pressionarmos “Enter”, o segundo será exibido e assim por diante. Como sabemos como são os prompts, podemos criar um script expect que os responda automaticamente para nós, sem qualquer interação. Aqui está:

#!/bin/expect 
spawn ./prompts.sh 
expect "What is your name?" { send "Egidio\n" }
expect "What is your country?" { send "Italy\n" }
expect "Enter your email address" { send "nomail@gmail.com\n" }
expect EOF

A primeira coisa que você deve notar é que usamos /bin/expect como interpretador de script, em vez de /bin/bash: isso é para evitar ser forçado a passar o script como argumento para o programa expect (não confunda com o nome do comando que podemos usar no script), cada vez que quisermos invocá-lo. Em nosso script trivial, usamos três comandos: spawn, expect e send.

O primeiro, spawn, executa um novo processo e conecta a saída padrão, a entrada padrão e os descritores de arquivo de erro padrão do último, para esperar, para que possa analisar as mensagens do programa e executar o script. ações.

O comando expect espera até que um determinado padrão corresponda à saída do executável iniciado com o comando spawn. No exemplo acima, a correspondência pode acontecer em qualquer lugar da saída. Se a saída do comando fosse: “Diga-me, qual é o seu país? ”, o padrão teria correspondido mesmo assim. Para impor uma correspondência mais estrita, poderíamos ter usado âncoras de expressão regular: ^ e $. Eles correspondem, respectivamente, ao início e ao fim do fluxo de dados.

Se o padrão não corresponder à saída e o tempo limite expirar, o comando expect retornará e a execução do script continuará na próxima instrução. O tempo limite padrão é 10 segundos; podemos alterá-lo atribuindo um valor diferente à variável “timeout”:

set timeout 20

No exemplo acima, definimos um tempo limite de 20 segundos; usar um valor -1 desativa completamente o tempo limite, de modo que expect espera indefinidamente, enquanto um valor 0 causa o comportamento oposto: expect não espera nada.

O último comando que usamos é send. O comandosend envia uma string para o processo. Observe que incluímos o caractere \n (fim de linha) na string que fornecemos, já que nenhuma formatação é aplicada por padrão.

Na última linha do script, ao invés de uma mensagem específica, combinamos EOF (End Of File). Salvamos o script como prompts.exp (a extensão “.exp” é apenas uma convenção) e o tornamos executável. Finalmente, nós o lançamos. Aqui está sua saída:

$ ./script.exp 
spawn ./prompts.sh
What is your name? Egidio
What is your country? Italy
Enter your email address: nomail@gmail.com

Gerar automaticamente scripts expect com autoexpect

Autoexpect é um utilitário que vem junto com expect: podemos usá-lo para gerar scripts expect como resultados de uma sessão interativa. Em vez de escrever um script expect manualmente, podemos usar autoexpect para executar o comando que requer interação do usuário, por exemplo:

$ autoexpect ./prompts.sh

O script que fornecemos como argumento para autoexpect é executado; requer nossa interação, como normalmente faria. Entretanto, assim que o script é encerrado, um script esperado é gerado: script.exp. Quando executado, ele replicará as ações que realizamos interativamente.

Pensamentos finais

Neste tutorial, aprendemos o básico sobre como usar o expect para automatizar comandos interativos. Vimos um exemplo muito básico de como escrever um script expect, usando os comandos spawn, expect e send. Por fim, vimos como é possível gerar automaticamente um script expect usando o utilitário autoexpect. Aqui mal arranhamos a superfície do que podemos alcançar usando scripts esperados. Por favor, dê uma olhada no manual expect para um conhecimento mais aprofundado.

Artigos relacionados: