Bash Scripting: automatiza o comando no console

2

Estou conectando a uma VPN por meio de um script simples, que gostaria de executar na inicialização do computador, portanto, preciso que ela seja totalmente automatizada. No entanto, o script executará "openconnect --jupiper" e solicitará minhas credenciais posteriormente (cerca de 3-4 segundos depois, quando adquirir uma conexão).

Eu gostaria que ele emitisse minhas credenciais depois que algum texto fosse encontrado (de maneira mais rápida e precisa) ou depois de um atraso definido (modo mudo e menos preciso).

Existe uma maneira de enviar comandos após um atraso definido ou após algum texto (correspondência de regex, por exemplo) ser retornado?

    
por Joao Carlos 02.03.2016 / 17:08

2 respostas

3

Para automatizar comandos, usei ao longo dos anos espero . É ótimo simular uma sessão interativa, seja ao lidar com comandos difíceis que exigem interatividade, ou para interagir com dispositivos ativos ou outros servidores em sua rede. Eu ainda uso para acessar o equipamento ativo, buscar algumas estatísticas e realizar backups automáticos.

Expect is a program that "talks" to other interactive programs according to a script. Following the script, Expect knows what can be expected from a program and what the correct response should be. An interpreted language provides branching and high-level control structures to direct the dialogue. In addition, the user can take control and interact directly when desired, afterward returning control to the script.

Usando o Expect Scripts para automatizar tarefas

Como exemplo, um script de expectativa que escrevi para testar o serviço POP:

#!/bin/sh
# \
exec expect "$0" ${1+"$@"}

set force_conservative 0  ;# set to 1 to force conservative mode even if
                          ;# script wasn't run conservatively originally
if {$force_conservative} {
        set send_slow {1 .1}
        proc send {ignore arg} {
                sleep .1
                exp_send -s -- $arg
        }
}

set timeout -1
spawn telnet 127.0.0.1 110
match_max 100000
expect {
"Hello"    { send -- "USER [email protected]\r"; exp_continue
       }
"assword" { send -- "PASS password\r" ; exp_continue
       }
"logged"   {
         send -- "LIST 1\r" ; exp_continue
   }
-re "failed|denied"   { exit
       }
"OK 1" { send -- "QUIT\r"; }
}

De acordo com minha conversa com @cas, eu também gostaria de salientar que o simples regexp espera que o subconjunto de linguagens seja útil para scripts de automações curtas / protótipos [muito] aproximados, junto com o bash.

Se houver necessidade de manipulação mais complicada da saída, o manuseio interativo pode / melhor ser feito com outra linguagem de programação.

Por exemplo, em python, pexpect , ou mesmo em C, usando libexpectar ou miniexpect .

Recentemente, com o movimento devops, você também tem toda uma série de novos [e antigos] frameworks para automatizar tarefas do sistema, como Ansible , Fantoche, sal.

Eles exigem, no entanto, uma curva de aprendizado e mais recursos. Eu pessoalmente sou a favor do Ansible.

Dica Ansível: executando Scripts Interativos com Ansible

    
por 02.03.2016 / 17:36
1

Na verdade, não consegui que o "openconnect" funcionasse corretamente com todos os argumentos da linha de comando, por isso acabei criando um script do Expect para ele.

A resposta de Rui F Ribeiro foi exatamente sobre o dinheiro, no entanto, eu precisava de um pouco mais de pesquisa para fazer tudo funcionar, coisas menores, variáveis e tal.

No interesse de quem já viu essa questão aqui, estou postando o roteiro que resolve o meu caso de uso para a questão original, não porque seja uma alternativa, mas porque é uma "extensão" da participação do conhecimento de Rui F Ribeiro.

#!/usr/bin/expect -f

set vpn_url "vpn.domain.com"
set vpn_username "theuser"
set vpn_password "thepassword"
set ubuntu_username "theubuntuloginuser"
set ubuntu_password "theubuntuloginpass"

set force_conservative 0  ;# set to 1 to force conservative mode even if
        ;# script wasn't run conservatively originally
if {$force_conservative} {
  set send_slow {1 .1}
  proc send {ignore arg} {
    sleep .1
    exp_send -s -- $arg
  }
}

set timeout -1
spawn $env(SHELL)
match_max 100000
send -- "sudo LD_LIBRARY_PATH=\"/usr/local/lib\" openconnect --juniper --no-cert-check $vpn_url -u $vpn_username\r"
expect {
  "password for $ubuntu_username:" {
    send -- "$ubuntu_password\r"
  }
}
expect -exact "password:"
send -- "$vpn_password\r"
expect eof
    
por 03.03.2016 / 11:07