Insere entrada automaticamente na linha de comando

85

Estou executando um script que solicita a inserção de 'y' em cada operação. Estou procurando uma solução como $ ./script < echo 'yyyyyyyyyyyyyy' para transmitir todas as minhas entradas de uma só vez.

    
por NewMrd 29.08.2013 / 14:05

6 respostas

166

Existe um comando criado especificamente para esse caso: yes

$ yes | ./script

O que o yes faz é imprimir repetidamente y seguido por uma nova linha para stdout. Se você conectar a saída de yes a outro comando usando um canal (a barra vertical), então o y seguido por nova linha irá para a entrada do outro comando.

Se você quer dizer não ( n ) ao invés de sim ( y ) você pode fazer assim:

$ yes n | ./script

Outros métodos para inserir entrada:

Se você sabe exatamente quantos y seu script está esperando, pode fazer assim:

$ printf 'y\ny\ny\n' | ./script

As novas linhas ( \n ) são as chaves de entrada.

Usando printf em vez de yes , você tem um controle de entrada mais refinado:

$ printf 'yes\nno\nmaybe\n' | ./script

Observe que, em alguns casos raros, o comando não exige que o usuário pressione enter após o caractere. Nesse caso, deixe as novas linhas:

$ printf 'yyy' | ./script

Para fins de integridade, você também pode usar um documento aqui :

$ ./script << EOF
y
y
y
EOF

Ou se o seu shell for compatível com uma string :

$ ./script <<< "y
y
y
"

Ou você pode criar um arquivo com uma entrada por linha:

$ ./script < inputfile

Se o comando for suficientemente complexo e os métodos acima não forem mais suficientes, você poderá usar espera .

Nitropice técnico:

A invocação do comando hipotético que você forneceu na sua pergunta não funciona:

$ ./script < echo 'yyyyyyyyyyyyyy'
bash: echo: No such file or directory

Isso ocorre porque a gramática do shell permite um operador de redirecionamento em qualquer lugar na linha de comando. No que diz respeito ao shell, sua linha de comando hipotética é a mesma que esta linha:

$ ./script 'yyyyyyyyyyyyyy' < echo
bash: echo: No such file or directory

Isso significa que ./script será chamado com o argumento 'yyyyyyyyyyyyyy' e o stdin receberá entrada de um arquivo chamado echo . E o bash reclama porque o arquivo não existe.

    
por lesmana 29.08.2013 / 14:08
6

Algumas coisas ( apt-get , por exemplo) aceitam sinalizadores especiais para serem executados no modo silencioso (e aceitam padrões). No caso de apt-get , basta passar um sinal -y . Isso depende completamente do seu script.

Se precisar de coisas mais complicadas, você pode incluir seu script em um script de expectativa. O expect permite que você leia a saída e envie dados para que você possa fazer coisas bem complicadas que outros scripts não permitiriam. Aqui está um dos exemplos da sua página da Wikipédia :

# Assume $remote_server, $my_user_id, $my_password, and $my_command were read in earlier
# in the script.
# Open a telnet session to a remote server, and wait for a username prompt.
spawn telnet $remote_server
expect "username:"
# Send the username, and then wait for a password prompt.
send "$my_user_id\r"
expect "password:"
# Send the password, and then wait for a shell prompt.
send "$my_password\r"
expect "%"
# Send the prebuilt command, and then wait for another shell prompt.
send "$my_command\r"
expect "%"
# Capture the results of the command into a variable. This can be displayed, or written to disk.
set results $expect_out(buffer)
# Exit the telnet session, and wait for a special end-of-file character.
send "exit\r"
expect eof
    
por Oli 29.08.2013 / 14:12
5

No shell script você também pode usar o seguinte truque de spawn, esperar e enviar

spawn script.sh
expect "Are you sure you want to continue connecting (yes/no)?"
send "yes"

No entanto, no scenerio acima você terá que dar a frase que você espera obter enquanto você executa o script para mais exemplos, vá para o seguinte link

Espere dentro do Bash

    
por Tarun 29.08.2013 / 14:35
4

Use o comando yes :

yes | script

Trecho da página do manual:

NAME
       yes - output a string repeatedly until killed

SYNOPSIS
       yes [STRING]...
       yes OPTION

DESCRIPTION
       Repeatedly output a line with all specified STRING(s), or 'y'.
    
por Peter W. Osel 11.04.2014 / 16:40
1

Ok, isso pode não ser uma solução muito elegante, mas se você escrever suas opções em um arquivo separado e passá-las como uma entrada para o script, também funcionará. Portanto, se você criar um novo arquivo com todas as suas opções (chame esse arquivo como 'options.in'), poderá executar facilmente seu script com ./script.sh < options.in e editar / criar diferentes opções de arquivos conforme apropriado.

    
por Sidhha 29.08.2013 / 17:50
0

Eu estava escrevendo um script bash com o Dialog e precisava que isso acontecesse automaticamente também. Eu fiz isso e funcionou como um encanto.

# -Wy force signaturewipe (if exists)
echo "y" | sudo lvcreate -W y -n $lvName -L "$lvSize"G /dev/"$svg" >> $nfsUtilLog
    
por Benjamin G. West 03.08.2017 / 18:05