Estou executando o Ubuntu Linux. Suponha que exista um programa chamado myprogram
. Este programa solicita a entrada do usuário; especificamente, o usuário deve digitar um número inteiro quando solicitado e pressionar Enter. Eu gostaria de automatizar esse processo usando um script bash. Em particular, eu gostaria de executar myprogram
, digamos, 100 vezes (usando um contador i
que passa de 1
para 100
). Em cada execução de myprogram
, gostaria de inserir o valor atual de i
quando solicitado.
(A propósito, myprogram
aceita opções / opções -options
, todas as quais serão constantes e, portanto, especificadas no script bash.)
Um esqueleto incompleto desse script bash pode ser:
#!/bin/bash
for i in {1..100}
do
myprogram -options
done
Agora eu gostaria de modificar o código acima para que o valor atual de i
seja inserido quando solicitado pelo programa. Qual é a melhor maneira de fazer isso?
O site do software que estou usando sugere usar <<EOF
no final da myprogram -options
linha. Eu acho que isso diz ao bash para olhar para o "final do arquivo" para a entrada usar. Mas e se eu não quiser colocar a entrada no final do arquivo? E se eu gostaria de colocá-lo imediatamente após o <<
ou <
?
A razão é que as coisas ficarão mais complicadas. Por exemplo, posso introduzir um contador inteiro j
que muda de alguma maneira não linear e não seqüencial. Gostaria, então, de alimentar o valor atual de j
para myprogram
em cada iteração, mas o valor de j
pode mudar entre a chamada myprogram -options
e o final do arquivo EOF
.
Você tem alguma sugestão?
Respostas:
Para quase todos os programas, ambos
echo $i | myprogram -options
emyprogram -options <<<$i
devem funcionar, alimentando o programa$i
por meio de entrada padrão.<foo
usará o conteúdo do arquivo nomeadofoo
como stdin.<<foo
usará o texto entre isso e uma linha consistindo apenasfoo
como entrada padrão. Este é um documento aqui (heredoc), como disse Gilles;EOF
na verdade não significa o final do arquivo, é apenas um delineador heredoc comum (usamos "foo" nesse exemplo).<<<foo
usará a string "foo" como entrada padrão. Você também pode especificar uma variável$foo
e o shell usará seu conteúdo como stdin, como mostrei acima. Isso é chamado de herestring , pois usa uma cadeia curta em contraste com um bloco inteiro, como em um heredoc. Herestrings funcionam no bash, mas não no/bin/sh
.fonte
A sintaxe recomendada por este site é chamada de documento aqui . A entrada para o programa de arquivo inicia imediatamente abaixo da linha que contém
<<EOF
, e não é finalizada no final do script, mas por uma linha que contém exatamente o textoEOF
(tome cuidado para não ter espaço em branco extra). A propósito, você pode usar qualquer marcador final que não contenha nenhum caractere especial do shell:EOF
não é uma palavra-chave, é apenas tradicional.fonte
END_OF_WHATEVER_FUNCTION
. Às vezes, tentar "economizar" espaço / tamanho é realmente um desperdício de esforço, pois causa ambiguidade quanto ao que realmente está acontecendo.sleep
ler comandos a partir do script?aqui os documentos mencionados por Kevin e Gilles acima, ou a tubulação simples funcionará em muitos casos.
Para situações mais complicadas, você pode procurar no 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 esperado é tcl), mas existem implementações para muitas linguagens de script comuns. É até possível escrever uma implementação muito primitiva da ideia em sh ou bash usando while e read.
A idéia geral do Expect e ferramentas similares é esperar por uma sequência ou padrão especificado na saída de um programa e, em seguida, alimentá-lo com a entrada desejada.
Um exemplo comum de uso é automatizar o login, "esperando" (ou seja, aguardando) a string "ogin:", envie o nome de login e, em seguida, espere a string "word:" e envie a senha.
Uma opção final, se você tiver a fonte do meu programa, é apenas modificá-lo para receber a entrada que você deseja fornecer como uma opção de linha de comando. Isso pode ser um pouco mais trabalhoso, mas será muito menos irritante do que mexer 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 o meu programa de volta para o upstream :) Mesmo que eles não gostem da maneira como você o codificou, eles podem gostar da idéia o suficiente para adicionar o recurso. Os desenvolvedores a montante tendem a apreciar as pessoas que ficam loucas e contribuem em vez de exigir ou reclamar.
fonte