J'utilise Ubuntu Linux. Supposons qu'il existe un programme appelé myprogram
. Ce programme invite l'utilisateur à entrer; en particulier, l'utilisateur doit saisir un entier à l'invite et appuyer sur Enter. Je voudrais automatiser ce processus en utilisant un script bash. En particulier, je voudrais exécuter myprogram
, disons, 100 fois (en utilisant un compteur i
qui va de 1
à 100
). À chaque exécution de myprogram
, je voudrais saisir la valeur actuelle de i
lorsque vous y êtes invité.
(Soit dit en passant, myprogram
prend les options / commutateurs -options
, qui seront tous constants et donc spécifiés dans le script bash.)
Un squelette incomplet de ce script bash pourrait être:
#!/bin/bash
for i in {1..100}
do
myprogram -options
done
Maintenant, je voudrais modifier le code ci-dessus afin que la valeur actuelle de i
soit entrée lorsque le programme le demande. Quelle est la meilleure façon de procéder?
Le site Web du logiciel que j'utilise suggère d' utiliser <<EOF
à la fin de la myprogram -options
ligne. Je pense que cela dit à bash de regarder la "fin du fichier" pour l'entrée à utiliser. Mais que faire si je ne souhaite pas placer l'entrée à la fin du fichier? Et si j'aimerais le mettre immédiatement après le <<
ou <
?
La raison en est que les choses deviendront plus compliquées. Par exemple, je peux introduire un compteur entier j
qui change d'une manière non linéaire et non séquentielle. Je voudrais ensuite alimenter la valeur actuelle de j
to myprogram
à chaque itération, mais la valeur de j
peut changer entre l'appel à myprogram -options
et la fin du fichier EOF
.
Avez-vous des suggestions?
Réponses:
Pour presque tous les programmes, à la fois
echo $i | myprogram -options
etmyprogram -options <<<$i
devraient fonctionner, en alimentant le programme$i
par une entrée standard.<foo
utilisera le contenu du fichier nomméfoo
stdin.<<foo
utilisera le texte entre celui-ci et une ligne composée uniquementfoo
comme entrée standard. C'est un document ici (heredoc), comme l'a dit Gilles;EOF
ne signifie pas en fait la fin du fichier, c'est juste un délimiteur hérédoc commun (nous utilisons plutôt "foo" dans cet exemple).<<<foo
utilisera la chaîne "foo" comme entrée standard. Vous pouvez également spécifier une variable$foo
, et le shell utilisera son contenu comme stdin, comme je l'ai montré ci-dessus. C'est ce qu'on appelle une chaîne héréditaire , car elle utilise une chaîne courte contrairement à un bloc entier, comme dans un hérédoc. Ses chaînes fonctionnent en bash, mais pas en/bin/sh
.la source
La syntaxe recommandée par ce site Web s'appelle un document ici . L'entrée dans le programme de fichiers commence immédiatement en dessous de la ligne contenant
<<EOF
, et elle n'est pas terminée à la fin du script, mais par une ligne contenant exactement le texteEOF
(attention à ne pas avoir d'espace supplémentaire). Soit dit en passant, vous pouvez utiliser n'importe quel marqueur de fin qui ne contient aucun caractère spécial shell:EOF
n'est pas un mot-clé, il est simplement traditionnel.la source
END_OF_WHATEVER_FUNCTION
. Parfois, essayer de «sauver» l'espace / la taille est en fait une perte d'effort car cela provoque une ambiguïté sur ce qui se passe réellement.sleep
entre les commandes lire le script?ici, les documents mentionnés par Kevin et Gilles ci-dessus, ou la simple tuyauterie fonctionnera dans de nombreux cas.
Pour des situations plus compliquées, vous voudrez peut-être examiner Expect ou similaire (par exemple, le module Expect :: Simple CPAN est une implémentation Perl très facile à utiliser). personnellement, je préfère le module perl (Attend lui-même est tcl) mais il existe des implémentations pour de nombreux langages de script courants. Il est même possible d'écrire une implémentation très primitive de l'idée en sh ou bash en utilisant while et read.
L'idée générale d'Expect et des outils similaires est d'attendre une chaîne ou un modèle spécifié dans la sortie d'un programme, puis de l'alimenter comme vous le souhaitez.
Un exemple courant d'utilisation est d'automatiser la connexion, en «attendant» (c'est-à-dire en attendant) la chaîne «ogin:», en envoyant le nom de connexion, puis en attendant la chaîne «mot:» et en envoyant le mot de passe.
Une dernière option, si vous avez la source de myprogram, consiste simplement à le modifier pour prendre l'entrée que vous voulez lui donner comme option de ligne de commande. Cela pourrait être un peu plus de travail à l'avance, mais sera beaucoup moins aggravant que de jouer avec Expect ou de transférer des données dans un programme qui n'a pas été conçu pour être utilisé de cette façon.
... et n'oubliez pas de soumettre votre patch à myprogram en amont :) Même s'ils n'aiment pas la façon dont vous l'avez codé, ils pourraient aimer l'idée de pouvoir ajouter eux-mêmes la fonctionnalité. Les développeurs en amont ont tendance à apprécier les gens qui descendent de leurs fesses et contribuent plutôt que d'exiger ou de se plaindre.
la source