Entrer automatiquement les entrées en ligne de commande


143

Je suis en train d'exécuter un script qui demande d'entrer «y» à chaque opération. Je cherche une solution comme $ ./script < echo 'yyyyyyyyyyyyyy'passer toutes mes entrées en même temps.


Parfois, l' -foption fonctionne bien avec certaines commandes.
iammilind

Réponses:


259

Il existe une commande créée spécifiquement pour ce cas: yes

$ yes | ./script

Ce que cela fait est de connecter la sortie de yesà l'entrée de ./script. Ainsi, lorsque ./scriptvous demandez une entrée utilisateur, il obtiendra le résultat de yes. La sortie de yesest un flux sans fin de ysuivi d'une nouvelle ligne. Donc, fondamentalement, comme si l'utilisateur entrait ypour chaque question de ./script.

Si vous voulez dire non ( n) au lieu de oui ( y), vous pouvez le faire comme ceci:

$ yes n | ./script

Notez que certains outils ont une option pour toujours considérer yescomme réponse. Voir par exemple ici: Ignorez l'invite yes / no dans 'apt-get upgrade'


Autres méthodes pour saisir une entrée:

Si vous savez exactement combien yvotre script en attend, vous pouvez le faire comme ceci:

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

Les nouvelles lignes ( \n) sont les touches d'entrée.

En utilisant à la printfplace de yesvous avez un contrôle plus fin des entrées:

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

Notez que dans certains cas rares, la commande ne nécessite pas que l'utilisateur appuie sur Entrée après le caractère. dans ce cas, laissez les nouvelles lignes:

$ printf 'yyy' | ./script

Par souci d’exhaustivité, vous pouvez également utiliser un document here :

$ ./script << EOF
y
y
y
EOF

Ou si votre shell supporte une chaîne ici :

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

Ou vous pouvez créer un fichier avec une entrée par ligne:

$ ./script < inputfile

Si la commande est suffisamment complexe et que les méthodes ci-dessus ne suffisent plus, vous pouvez utiliser expect .

Voici un exemple de script attendu super simple:

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

Nitpick technique:

L'invocation de commande hypothétique que vous avez donnée dans votre question ne fonctionne pas:

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

En effet, la grammaire du shell autorise un opérateur de redirection n'importe où dans la ligne de commande. En ce qui concerne le shell, votre ligne de commande hypothétique est la même que cette ligne:

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

Cela signifie que ./scriptsera appelé avec l'argument 'yyyyyyyyyyyyyy'et le stdin obtiendra l'entrée d'un fichier nommé echo. Et bash se plaint puisque le fichier n'existe pas.


1
Je reçois un cannot enable tty mode on non tty input. Souhaitez-vous connaître une solution de contournement pour cela?
bmpasini

Lorsque j'essaie l' printfastuce avec un runfichier dont je dois automatiser le processus d'installation, tout ce qui se passe est que je reçois un message d'erreur Warning: Tried to connect to session manager, None of the authentication protocols specified are supported, et le script s'ouvre dans un nouveau terminal et me demande de saisir mon entrée manuellement, comme d'habitude. Cela se passe d'ailleurs sur Debian. Aucune suggestion?
DavidB

besoin de plus de détails. trop gros pour les commentaires. veuillez poser une nouvelle question avec tous les détails. vous pouvez mettre un lien ici.
lesmana

rien ne marche avec 'vagrant destroy' sur centos
Drew

Wicked facile! Fonctionne sur les importations de données SQL Google Beta SQL Cloud! Très appréciée!
G_Style

11

Utilisez la commande yes:

yes | script

Extrait de la page de manuel:

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

Certaines choses ( apt-getpar exemple) acceptent que des indicateurs spéciaux soient exécutés en mode silencieux (et acceptent les valeurs par défaut). Dans apt-getle cas de, vous passez juste un -ydrapeau. Cela dépend complètement de votre script cependant.

Si vous avez besoin de choses plus compliquées, vous pouvez envelopper votre script dans un script attendu. expect vous permet de lire la sortie et d'envoyer des entrées afin que vous puissiez faire des choses assez compliquées que d'autres scripts ne permettraient pas. Voici l' un des exemples de sa page 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

Cela ne peut pas être utilisé avec un .shscript shell, non? Ou y a-t-il un moyen?
Shayan

7

Dans le script shell, vous pouvez également utiliser le truc suivant: spawn, expect et send

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

Cependant, dans le scénario ci-dessus, vous devrez donner la phrase que vous espérez obtenir pendant que vous exécutez le script pour plus d'exemples, cliquez sur le lien suivant

Attendez-vous à Bash


2

D'accord, ce n'est peut-être pas une solution très élégante, mais si vous écrivez vos options dans un fichier séparé et que vous le transmettez ensuite en tant qu'entrée au script, cela fonctionnera également. Ainsi, si vous créez un nouveau fichier avec toutes vos options (appelez ce fichier sous le nom "options.in"), vous pourrez alors exécuter facilement votre script avec ./script.sh < options.inet éditer / créer différents fichiers d'options selon vos besoins.


Comment dois-je écrire le options.infichier? Pouvez-vous donner un exemple?
Shayan

0

J'écrivais un script bash avec Dialog et j'avais besoin que cela se produise automatiquement aussi. Je l'ai fait et cela a fonctionné comme un charme.

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

-1

Vous pouvez fournir une entrée utilisateur à votre script avec cat, à partir d'un fichier texte, redirigé vers votre script avec bashcomme ceci:

cat input.txt | bash your_script.sh

Il vous suffit de saisir les informations de votre choix dans votre fichier input.txt, quelles que soient les réponses souhaitées: y, n, chiffres, chaînes, etc.



@muru Pour moi, la solution que vous avez mentionnée n'a pas fonctionné et je dois donc inventer la mienne.
WebComer

Peu probable. Vous décrivez tous les deux la même chose.
muru

@muru La même idée de fournir des réponses à partir d'un fichier (ce qui peut être fait de plusieurs manières) n'est pas la même chose, et en plus, elle a abouti à une tout autre manière. Vous devriez pouvoir le voir. Si la solution que vous proposez fonctionnerait pour moi, je ne passerais pas mon temps à réinventer la roue aujourd'hui. Vous pouvez utiliser n'importe quel travail pour vous.
WebComer

@muru Je crois qu'il y a une différence entre les deux, dont certaines décrites dans les réponses disent ici askubuntu.com/questions/172982/… . Pour moi, par exemple, mon code si la sortie est redirigée vers un fichier semble plus clair comme un flux naturel de gauche à droite. Après tout, voter contre des solutions qui fonctionnent bien comme vous n’incite pas les gens à partager leurs solutions ici. Je pense que cela est suffisant pour éliminer le vote négatif.
WebComer
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.