Automatizando a entrada de texto de um script bash sem usar EOF

Automatizando a entrada de texto de um script bash sem usar EOF

Estou executando o Ubuntu Linux. Suponha que exista um programa chamado myprogram. Este programa solicita entrada do usuário; especificamente, o usuário deve digitar um número inteiro quando solicitado e pressionar Enter. Gostaria de automatizar esse processo usando um script bash. Em particular, eu gostaria de executar myprogram, digamos, 100 vezes (usando um contador ique vai de 1até 100). Em cada execução de myprogram, gostaria de inserir o valor atual de iquando solicitado.

(A propósito, myprogramleva options/switches -options, todos os quais serão constantes e, portanto, especificados no script bash.)

Um esqueleto incompleto deste script bash pode ser:

#!/bin/bash
for i in {1..100}
do
   myprogram -options
done

Agora gostaria de modificar o código acima para que o valor atual de iseja inserido quando solicitado pelo programa. Qual é a melhor maneira de fazer isso?

O site do software que estou usando sugereusando <<EOFno final da myprogram -optionslinha. Eu acho que isso diz ao bash para olhar no "fim do arquivo" a entrada a ser usada. Mas e se eu não quiser colocar a entrada nofimdo arquivo? E se eu quiser colocá-lo imediatamente após o <<ou <?

A razão é que as coisas ficarão mais complicadas. Por exemplo, posso introduzir um contador inteiro jque muda de alguma forma não linear e não sequencial. Eu gostaria então de alimentar o valor atual de jto myprogramem cada iteração, mas o valor de jpode mudar entre a chamada myprogram -optionse o final do arquivo EOF.

Você tem alguma sugestão?

Responder1

Para quase todos os programas, ambos echo $i | myprogram -optionse myprogram -options <<<$idevem funcionar, alimentando o programa $iatravés de entradas padrão.

<foousará o conteúdo do arquivo denominado foostdin.

<<foousará o texto entre isso e uma linha que consiste apenas foocomo entrada padrão. Isto é umaqui documento(heredoc), como disse Gilles; EOFna verdade não significa o fim do arquivo, é apenas um delineador heredoc comum (usamos "foo" neste exemplo).

<<<foousará a string "foo" como entrada padrão. Você também pode especificar uma variável $fooe o shell usará seu conteúdo como stdin, como mostrei acima. Isso é chamado decorda hereditária, pois usa uma string curta em contraste com um bloco inteiro, como em um heredoc. Herestrings funcionam no bash, mas não no /bin/sh.

Responder2

A sintaxe recomendada por este site é chamada deaqui documento. A entrada para o programa de arquivo começa imediatamente abaixo da linha que contém <<EOFe não termina no final do script, mas por uma linha que contém exatamente o texto EOF(tome cuidado para não ter espaços em branco extras). A propósito, você pode usar qualquer marcador final que não contenha nenhum caractere especial do shell: EOFnão é uma palavra-chave, é meramente tradicional.

#!/bin/bash
for i in {1..100}
do
   myprogram -options <<EOF
$i
EOF
   for j in {1..42}; do
     myprogram2 <<EOF
$i
$j
EOF
   done
done

Responder3

aqui, documentos mencionados por Kevin e Gilles acima, ou tubulação simples funcionarão em muitos casos.

Para situações mais complicadas, você pode querer olhar para Expect ou similar (por exemplo, o módulo Expect::Simple CPAN é uma implementação Perl muito fácil de usar). pessoalmente, prefiro o módulo perl (o próprio Expect é tcl), mas existem implementações para muitas linguagens de script comuns. É até possível escrever ummuitoimplementação primitiva da ideia em sh ou bash usando while e read.

A ideia geral do Expect e de ferramentas semelhantes é esperar por uma string ou padrão especificado na saída de um programa e, em seguida, alimentá-lo com a entrada desejada.

Um exemplo de uso comum é automatizar o login, "esperando" (ou seja, aguardando) a string "ogin:", enviando o nome de login, depois esperando a string "word:" e enviando a senha.

Uma opção final, se você tiver a fonte do myprogram, é apenas modificá-la para receber a entrada que deseja fornecer como uma opção de linha de comando. Isso pode ser um pouco mais trabalhoso no início, mas será muito menos agravante do que brincar com o Expect ou canalizar dados para um programa que não foi projetado para ser usado dessa maneira.

... e não se esqueça de enviar seu patch para myprogram back upstream :) Mesmo que eles não gostem da maneira como você o codificou, eles podem gostar da ideia o suficiente para adicionar o recurso eles mesmos. Os desenvolvedores upstream tendem a apreciar as pessoas que se levantam e contribuem, em vez de exigir ou reclamar.

informação relacionada