Faça com que o script bash responda aos prompts interativos [duplicado]

109

É possível fazer com que um script bash manipule automaticamente os prompts que normalmente seriam apresentados ao usuário com ações padrão? Atualmente, estou usando um script bash para chamar uma ferramenta interna que exibirá prompts para o usuário (solicitando S / N) para concluir as ações, no entanto, o script que estou escrevendo precisa ser completamente "sem intervenção", Preciso de uma forma de enviar Y|Nao prompt para permitir que o programa continue a execução. Isso é possível?

TJ L
fonte
isso não é "autocompletar" ... como @unwind diz, é "automação"
benzaita
3
Exemplo de uso yespara fazer isso: unix.stackexchange.com/questions/47344/…
Droogans

Respostas:

65

Isso não é "autocompletar", é automação. Uma ferramenta comum para essas coisas é chamada Expect .

Você também pode se safar apenas com a entrada de tubulação de yes.

desanuviar
fonte
3
Infelizmente, não posso usar o expect, pois há requisitos de espaço rigorosos no sistema que está executando isso, então não posso adicionar pacotes extras, mas a conexão yesresolveu, felizmente todos os prompts exigiam apenas um 'y' de qualquer maneira. Obrigado.
TJ L
No entanto, Yes | commandpode não funcionar sempre. Se for apenas para fins de instalação, então acho que -yé uma opção melhor e preferida.
Umesh Kaushik de
169

Um simples

echo "Y Y N N Y N Y Y N" | ./your_script

Isso permite que você passe qualquer sequência de "S" ou "N" para o seu script.

Loïc Février
fonte
3
Se eu precisasse enviar algum N, teria usado esse método, mas só precisava de Ys, então continuei yes. Pena que não posso aceitar duas respostas, pois ambas estão corretas.
TJ L
3
;) Bem, se algum dia você precisar enviar algum, Nagora você tem uma boa maneira de fazê-lo.
Loïc Février
2
Isso não funciona para mim; espaços não contam como novas linhas --- se, por exemplo, ecoar "Y N", ele fornecerá a string "Y N"como entrada para o primeiro prompt e ficará suspenso no segundo prompt, esperando que eu o conclua. Eu tentei mudar os espaços para novas linhas, mas também não funcionou, ainda deu uma string literal para o prompt.
Temporary_user_name
52
tente usar printf 'y\ny\ny\n' | ./your_script. Desta forma, você está inserindo manualmente a nova linha para cada entrada esperada.
Majid
8
printf '%s\n' Y Y N N Y N Y Y Ncoloca novas linhas entre os itens, mas sem precisar de uma string de formato grande.
Charles Duffy
16

Descobri que a melhor maneira de enviar entrada é usar cat e um arquivo de texto para transmitir qualquer entrada de que você precisa.

cat "input.txt" | ./Script.sh
Alex
fonte
Esperar não funcionou como esperado para mim. Esta é a melhor e mais simples resposta a esta pergunta.
cloudxix
12

Se você só tem Y para enviar:

$> yes Y |./your_script

Se você tiver apenas N para enviar:

$> yes N |./your_script
douardo
fonte
9

Na minha situação, precisei responder a algumas perguntas sem S ou N, mas com texto ou em branco. Descobri que a melhor maneira de fazer isso na minha situação era criar um arquivo shellscript. No meu caso, chamei de autocomplete.sh

Eu estava precisando responder a algumas perguntas de um exportador de esquema de doutrina, então meu arquivo ficou assim.

- Este é apenas um exemplo -

php vendor/bin/mysql-workbench-schema-export mysqlworkbenchfile.mwb ./doctrine << EOF
`#Export to Doctrine Annotation Format`                                     1
`#Would you like to change the setup configuration before exporting`        y
`#Log to console`                                                           y
`#Log file`                                                                 testing.log
`#Filename [%entity%.%extension%]`
`#Indentation [4]`
`#Use tabs [no]`
`#Eol delimeter (win, unix) [win]`
`#Backup existing file [yes]`
`#Add generator info as comment [yes]`
`#Skip plural name checking [no]`
`#Use logged storage [no]`
`#Sort tables and views [yes]`
`#Export only table categorized []`
`#Enhance many to many detection [yes]`
`#Skip many to many tables [yes]`
`#Bundle namespace []`
`#Entity namespace []`
`#Repository namespace []`
`#Use automatic repository [yes]`
`#Skip column with relation [no]`
`#Related var name format [%name%%related%]`
`#Nullable attribute (auto, always) [auto]`
`#Generated value strategy (auto, identity, sequence, table, none) [auto]`
`#Default cascade (persist, remove, detach, merge, all, refresh, ) [no]`
`#Use annotation prefix [ORM\]`
`#Skip getter and setter [no]`
`#Generate entity serialization [yes]`
`#Generate extendable entity [no]`                                          y
`#Quote identifier strategy (auto, always, none) [auto]`
`#Extends class []`
`#Property typehint [no]`
EOF

O que eu gosto nessa estratégia é que você pode comentar quais são suas respostas e, usando EOF, uma linha em branco é apenas isso (a resposta padrão). Acontece que essa ferramenta exportadora tem sua própria versão JSON para responder a essas perguntas, mas descobri isso depois de fazer isso =).

para rodar o script simplesmente esteja no diretório que você deseja e rode 'sh autocomplete.sh'no terminal.

Resumindo, usando << EOL & EOF em combinação com Return Lines, você pode responder a cada pergunta do prompt conforme necessário. Cada nova linha é uma nova resposta.

Meu exemplo apenas mostra como isso pode ser feito com comentários também usando o caractere `para que você se lembre de cada etapa.

Observe que a outra vantagem deste método é que você pode responder com mais do que apenas S ou N ... na verdade, você pode responder com espaços em branco!

Espero que isso ajude alguém.

Joseph Astrahan
fonte
4

Existe um utilitário especial para isso - ' sim '.

Para responder a todas as perguntas com a mesma resposta, você pode executar

yes [answer] |./your_script

Ou você pode colocá-lo dentro do seu script para ter uma resposta específica para cada pergunta

Asaf Pinhassi
fonte
como posso fazer isso dentro do script? quero especificar respostas diferentes para cada pergunta
Sengo