Passer des arguments à un programme interactif de manière non interactive

115

J'ai un script bash qui utilise la readcommande pour lire les arguments des commandes de manière interactive, par exemple les options oui / non. Existe-t-il un moyen d'appeler ce script dans un script non interactif en passant des valeurs d'option par défaut en tant qu'arguments?

Ce n'est pas seulement une option que je dois passer au script interactif.

sidharth sharma
la source
2
S'il lit depuis stdin, vous pouvez diriger votre entrée
lc.
4
Comme cette question reçoit de nombreux doublons, il convient de souligner que la langue dans laquelle le programme interactif est écrit n'a pas d'importance. Cela peut être un programme C qui lit l'entrée standard, ou une application Erlang, ou autre. Il y a quelque chose qui s'exécute à partir de la ligne de commande et qui demande odieusement une entrée interactive, et vous aimeriez l'automatiser.
tripleee
Bien sûr, si vous contrôlez l'application désagréable, réécrivez-la pour qu'elle puisse lire les réponses de manière non interactive (via un fichier de configuration, des options de ligne de commande ou autre). Ceci est beaucoup plus fiable et résistant à la modification de l'ordre ou du libellé des questions interactives.
tripleee

Réponses:

46

Pour des tâches plus complexes, il existe expect( http://en.wikipedia.org/wiki/Expect ). Il simule essentiellement un utilisateur, vous pouvez coder un script comment réagir aux sorties spécifiques du programme et aux éléments associés.

Cela fonctionne également dans des cas comme sshcelui qui interdit de lui envoyer des mots de passe.

Dani Gehtdichnixan
la source
8
... Bien que la solution appropriée dans le cas SSH soit de passer à l'authentification par clé publique.
tripleee
154

Plusieurs façons

pipe votre entrée

echo "yes
no
maybe" | your_program

rediriger depuis un fichier

your_program < answers.txt

utiliser un document ici (cela peut être très lisible)

your_program << ANSWERS
yes
no
maybe
ANSWERS

utiliser une chaîne ici

your_program <<< $'yes\nno\nmaybe\n'
Glenn Jackman
la source
5
Il convient de souligner que cela ne fonctionne que si le programme lit l'entrée standard. Certains programmes se mettent en quatre pour lire, par exemple, les mots de passe de manière interactive, même lorsque l'entrée standard est un tube. Pour les mots de passe, cela a du sens pour des raisons de sécurité; bien que certains programmes interactifs soient simplement mal conçus.
tripleee
@tripleee Dans le prolongement de ce que vous avez dit, comment un script lit-il les mots de passe qui ne sont pas affectés par stdin? Je sais que vous pouvez utiliser readpour saisir stdin, quelle fonction pouvez-vous utiliser pour faire ce que vous avez décrit?
flow2k
Dans ce cas, vous devez voir si le programme avec lequel vous essayez d'interagir dispose d'un moyen spécial pour lui envoyer l'entrée (par exemple, sshpass, ssh-agent), ou utilisez expect pour écrire l'interaction.
glenn jackman
2
Ce que font des programmes comme Expect, c'est d'exécuter le client sous un pseudo-terminal où il ressemble au client comme s'il y avait un utilisateur avec un terminal et un clavier à l'autre extrémité. Vous ne pouvez pas faire cela avec une pipe ordinaire.
tripleee
Avis important. Cela ne fonctionne pas si nous ajoutons des espaces aux commandes fournies.
71GA
13

Vous pouvez mettre les données dans un fichier et le rediriger comme ceci:

$ cat file.sh
#!/bin/bash

read x
read y
echo $x
echo $y

Données pour le script:

$ cat data.txt
2
3

Exécution du script:

$ file.sh < data.txt
2
3
Gourou
la source
7

Je veux juste ajouter un autre moyen. Je l'ai trouvé ailleurs, et c'est assez simple. Dites que je veux passer oui pour toutes les invites en ligne de commande pour une commande "execute_command", alors je dirais simplement oui.

yes | execute_command

Cela utilisera oui comme réponse à toutes les invites oui / non.


la source
2

Vous pouvez également utiliser printf pour diriger l'entrée vers votre script.

var=val
printf "yes\nno\nmaybe\n$var\n" | ./your_script.sh
Spanchan
la source
C'est ce qui m'a sauvé. Merci @spanchan.
sk001
0

une autre alternative peut être

echo "something" | tee /path/to/file

La commande tee imprime l'entrée qu'elle reçoit à l'écran et l'enregistre dans un fichier en même temps.

Prafulla Kumar Sahu
la source