Inserisci automaticamente input nella riga di comando


143

Sto eseguendo uno script che richiede di inserire 'y' in ogni operazione, sto cercando una soluzione come $ ./script < echo 'yyyyyyyyyyyyyy'passare tutti i miei input in una volta.


A volte l' -fopzione funziona bene con determinati comandi.
iammilind,

Risposte:


259

Esiste un comando creato appositamente per quel caso: yes

$ yes | ./script

Ciò che fa è collegare l'output di yesall'ingresso di ./script. Quindi, quando ./scriptchiede l'input dell'utente, otterrà invece l'output di yes. L'output di yesè un flusso infinito di yseguito da una nuova riga. Quindi, in pratica, come se l'utente stesse entrando yper ogni domanda ./script.

Se vuoi dire no ( n) invece di yes ( y) puoi farlo in questo modo:

$ yes n | ./script

Si noti che alcuni strumenti hanno un'opzione per assumere sempre yescome risposta. Vedi qui per esempio: ignora il prompt sì / no in 'apt-get upgrade'


Altri metodi per inserire l'input:

Se sai esattamente quanto il ytuo script si aspetta puoi farlo in questo modo:

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

Le newline ( \n) sono le chiavi di invio.

Usando printfinvece di yeste hai un controllo più fine dell'input:

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

Si noti che in alcuni rari casi il comando non richiede all'utente di premere Invio dopo il carattere. in tal caso, lasciare fuori le righe:

$ printf 'yyy' | ./script

Per completezza puoi anche usare un documento qui :

$ ./script << EOF
y
y
y
EOF

O se la tua shell lo supporta una stringa qui :

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

Oppure puoi creare un file con un input per riga:

$ ./script < inputfile

Se il comando è sufficientemente complesso e i metodi sopra non sono più sufficienti, è possibile utilizzare aspettarsi .

Ecco un esempio di uno script di attesa super semplice:

spawn ./script
expect "are you sure?"
send "yes\r"
expect "are you really sure?"
send "YES!\r"
expect eof

Nitpick tecnico:

L'ipotetica chiamata di comando che hai dato alla tua domanda non funziona:

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

Questo perché la grammatica della shell consente a un operatore di reindirizzamento in qualsiasi punto della riga di comando. Per quanto riguarda la shell, la tua ipotetica riga di comando è la stessa di questa riga:

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

Ciò significa ./scriptche verrà chiamato con l'argomento 'yyyyyyyyyyyyyy'e lo stdin otterrà l'input da un file denominato echo. E bash si lamenta poiché il file non esiste.


1
Ho un cannot enable tty mode on non tty input. Sapresti una soluzione per questo?
bmpasini,

Quando provo il printftrucco con un runfile di cui ho bisogno per automatizzare il processo di installazione, tutto ciò che succede è che viene visualizzato un messaggio di errore Warning: Tried to connect to session manager, None of the authentication protocols specified are supportede lo script si apre in un nuovo terminale e mi chiede di inserire manualmente il mio input come al solito. A proposito, questo sta succedendo su Debian. Eventuali suggerimenti?
DavidB,

bisogno di maggiori dettagli. troppo grande per i commenti. per favore fai una nuova domanda con tutti i dettagli. puoi mettere un link qui.
lesmana,

nulla funziona con 'vagrant destro' su centos
Drew

Malvagio facile! Funziona sulle importazioni di dati SQL di Google Cloud Beta! Molto apprezzato!
G_Style

11

Usa il comando yes:

yes | script

Estratto dalla pagina man:

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'.

9

Alcune cose ( apt-getad esempio) accettano flag speciali per l'esecuzione in modalità silenziosa (e accettano i valori predefiniti). Nel apt-getcaso, basta passare una -ybandiera. Questo dipende completamente dal tuo script.

Se hai bisogno di cose più complicate, puoi avvolgere il tuo script in uno script prevede. aspettarsi ti permette di leggere l'output e inviare l'input in modo da poter fare cose piuttosto complicate che altri script non permetterebbero. Ecco uno degli esempi dalla sua pagina Wikipedia :

# 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

Questo non può essere usato con uno .shscript di shell, giusto? O c'è un modo?
Shayan,

7

Nello script della shell puoi anche usare il seguente trucco di spawn, aspetta e invia

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

Tuttavia, nello scenario sopra riportato dovrai dare la frase che ti aspetti di ottenere mentre esegui lo script per ulteriori esempi vai al seguente link

Aspettatevi all'interno di Bash


2

Ok, questa potrebbe non essere una soluzione molto elegante ma se scrivi le tue opzioni in un file separato e poi le passi come input allo script, funzionerebbe anche. Quindi, se crei un nuovo file con tutte le tue opzioni (chiama questo file come 'options.in'), puoi facilmente eseguire lo script con ./script.sh < options.ine modificare / creare diversi file di opzioni come appropriato.


Come devo scrivere il options.infile? Puoi fare un esempio?
Shayan,

0

Stavo scrivendo uno script bash con Dialog e avevo bisogno che ciò avvenisse anche automaticamente. L'ho fatto e ha funzionato come un fascino.

# -Wy force signaturewipe (if exists)
echo "y" | sudo lvcreate -W y -n $lvName -L "$lvSize"G /dev/"$svg" >> $nfsUtilLog

-1

Puoi fornire l'input dell'utente al tuo script con cat, da un file di testo, reindirizzato al tuo script in bashquesto modo:

cat input.txt | bash your_script.sh

Basta inserire l'input dell'utente desiderato nel file input.txt, qualunque sia la risposta desiderata: y, n, cifre, stringhe, ecc.



@muru Per me, la soluzione che hai menzionato non ha funzionato, quindi devo inventare la mia.
WebComer,

Improbabile. Entrambi descrivete la stessa cosa.
muru,

L'idea di @muru Alike di fornire risposte dal file (che può essere fatto in diversi modi) non è la stessa cosa, e inoltre ha ottenuto un modo completamente diverso. Dovresti essere in grado di vederlo. Se la soluzione da te indicata funzionasse per me, oggi non passerò il tempo a reinventare la ruota. Puoi usare qualunque lavoro per te.
WebComer

@muru Credo che ci sia una differenza tra i due, alcuni dei quali descritti nelle risposte dicono qui askubuntu.com/questions/172982/… . Per me, ad esempio, il mio codice se l'output viene reindirizzato al file sembra più chiaro come un flusso naturale da sinistra a destra. Dopotutto, il downvoting che funziona bene soluzioni come te non stimola le persone a condividere le loro soluzioni qui. Credo che detto sia sufficiente per rimuovere il downvoting.
WebComer,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.