'Interact' não está funcionando como esperado no script bash / expect

1

Para provisionar um dispositivo incorporado (ou seja, gravar imagens em flash), uma série de comandos muito conhecidos deve ser inserida durante o estágio de inicialização. O algoritmo é algo como:

  • Capture um shell de carregador de inicialização digitando qualquer tecla durante a inicialização
  • Imagem em Flash A
  • imagem em Flash B
  • ...
  • Continuar a inicialização (com novas imagens)

Como devemos primeiro capturar o shell do gerenciador de inicialização em um determinado ponto no processo de inicialização, concluí que a aplicação de um script expect resolveria bem esse problema. Eu também gostaria de misturar alguns outros comandos bash para implementar a lógica em relação a qual nó de dispositivo se conectar, etc. O que eu criei (apenas a parte esperada) é o seguinte:

#!/bin/bash
DEVICE=...
FLASH_CMD_A=...
#Other bash stuff

expect <<SCRIPT
    set timeout 5
    spawn plink -serial -sercfg 115200,8,n,1 $DEVICE 

    expect "Hit any key to stop autoboot"
        sleep 1
        send "\r"

    expect "=>"
        sleep 1
        send "$FLASH_CMD_A\n"

    interact   
SCRIPT

echo "Done!"

O que estou observando é: A primeira linha de espera está sendo capturada corretamente, o sono está funcionando e a nova linha parece estar sendo enviada. A próxima expectativa (capturar o prompt) e seu sono correspondente também parece estar funcionando. O comando send ($ FLASH_CMD_A) é impresso no terminal com muitos espaços em branco entre as palavras, mas parece estar funcionando também.

O maior problema é que interact não parece estar fazendo nada. Uma vez que o segundo expect / send é executado, eu sou devolvido a um shell bash sem nunca ter visto "Done!" impresso na stdout. Eu também tentei a sintaxe de interação:

interact {
    "=>"{
        send "\r"
        exp_continue
    }
}

Mas isso não funcionou em tudo . O prompt nunca foi capturado e o script acabou de sair imediatamente, como se a instrução interact não estivesse lá. Alguma idéia do que eu posso estar fazendo errado? Eu tenho:

expect -v
expect version 5.45

Embora os comandos pareçam estarem sendo passados para o dispositivo, não posso ter certeza. Uma vez que eu sou devolvido para um shell bash, toda a saída do dispositivo após esses comandos é perdida. No entanto, se eu executar meu script uma segunda vez, o expect parece despejar seu buffer de texto ( expect_out ?) E sair imediatamente. Curiosamente, a saída que eu esperava dos comandos enviados anteriormente está contida nesse dump de buffer.

Como um aparte: Eu tentei esse mesmo script dentro de um ambiente de VM e nenhuma das declarações de "expectativa" estava sendo capturada; todas as entradas foram impressas para stdout e passadas.

    
por sherrellbc 11.07.2016 / 18:15

1 resposta

0

Como solução alternativa, execute o script de espera a partir de um arquivo, e não via entrada padrão:

#!/bin/sh

BLAH='echo hi'

ESCRIPT='mktemp runner.XXXXXXXXXX' || exit 1

# nope
#expect -d - <<SCRIPT
cat >$ESCRIPT <<SCRIPT
  set timeout 5
  spawn $SHELL
  # FIXME whatever your prompt looks like
  expect -ex "% "
  send -raw "\r"
  expect -ex "% "
  send -- "$BLAH\n"
  expect -ex "% "
  interact
SCRIPT

expect -d $ESCRIPT

echo alas poor $SHELL I knew him well a man of infinit

# and probably also 'trap' in the event this code gets whapped with an INT
# or something...
rm $ESCRIPT
    
por 11.07.2016 / 20:15