web-dev-qa-db-fra.com

Entrer automatiquement les entrées en ligne de commande

J'exécute un script qui demande d'entrer "y" à chaque opération. Je recherche une solution telle que $ ./script < echo 'yyyyyyyyyyyyyy' pour transmettre toutes mes entrées en une seule fois.

127
NewMrd

Une commande a été créée spécifiquement pour ce cas: yesname__

$ yes | ./script

Cela permet de connecter l'entrée de ./script à la sortie de yesname__. Ainsi, lorsque ./script demande à l'utilisateur d'entrer, il obtiendra plutôt la sortie de yesname__. La sortie de yesest un flux sans fin de ysuivi d'une nouvelle ligne. Donc, fondamentalement, comme si l'utilisateur saisissait ypour chaque question de ./script.

Si vous voulez dire non (nname__) à la place de oui (yname__), procédez comme suit:

$ yes n | ./script

Notez que certains outils offrent une option pour ne pas demander et toujours supposer yescomme réponse. Voir par exemple ici: Contourner l'invite yes/no dans 'apt-get upgrade'


Autres méthodes pour saisir une entrée:

Si vous savez exactement combien de yvotre script attend, procédez comme suit:

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

Les nouvelles lignes (\n) sont les touches de saisie.

En utilisant printfau lieu de yesname__, vous disposez d'un contrôle plus détaillé de l'entrée:

$ 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 ici document :

$ ./script << EOF
y
y
y
EOF

Ou si votre Shell le supporte un ici chaîne :

$ ./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 ./script sera appelé avec l'argument 'yyyyyyyyyyyyyy' et que le stdin sera entré à partir d'un fichier nommé echoname__. Et bash se plaint puisque le fichier n'existe pas.

232
lesmana

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'.
10
Peter W. Osel

Certaines choses (apt-get par exemple) acceptent les drapeaux spéciaux pour s'exécuter en mode silencieux (et acceptent les valeurs par défaut). Dans le cas de apt-get, il vous suffit de lui passer un drapeau -y. 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 n 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
8
Oli

Dans le script Shell, vous pouvez également utiliser l'astuce suivante: spawn, expect and 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

7
Tarun

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 pouvez facilement exécuter votre script avec ./script.sh < options.in et éditer/créer différents fichiers d'options selon vos besoins.

2
Sidhha

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
0
Benjamin West