Automatisieren der Texteingabe aus einem Bash-Skript ohne Verwendung von EOF

Automatisieren der Texteingabe aus einem Bash-Skript ohne Verwendung von EOF

Ich verwende Ubuntu Linux. Angenommen, es gibt ein Programm namens myprogram. Dieses Programm fordert den Benutzer zur Eingabe auf; genauer gesagt muss der Benutzer bei entsprechender Aufforderung eine Ganzzahl eingeben und drücken Enter. Ich möchte diesen Prozess mithilfe eines Bash-Skripts automatisieren. Insbesondere möchte ich myprogrambeispielsweise 100 Mal ausführen (mit einem Zähler, der von bis igeht ). Bei jeder Ausführung von möchte ich bei entsprechender Aufforderung den aktuellen Wert von eingeben . 1100myprogrami

(Übrigens myprogramwerden Optionen/Schalter akzeptiert -options, die alle konstant sind und somit im Bash-Skript angegeben werden.)

Ein unvollständiges Gerüst dieses Bash-Skripts könnte wie folgt aussehen:

#!/bin/bash
for i in {1..100}
do
   myprogram -options
done

Nun möchte ich den obigen Code so ändern, dass iauf Nachfrage des Programms der aktuelle Wert von eingetragen wird. Wie kann ich das am besten bewerkstelligen?

Die Website der von mir verwendeten Software schlägt vorusing <<EOFam Ende der myprogram -optionsZeile. Ich denke, das sagt bash, dass es am „Ende der Datei“ nach der zu verwendenden Eingabe suchen soll. Aber was, wenn ich die Eingabe nicht am Ende der Zeile platzieren möchte?Ende<<der Datei? Was ist, wenn ich es direkt nach dem oder einfügen möchte <?

Der Grund dafür ist, dass die Dinge komplizierter werden. Ich könnte beispielsweise einen ganzzahligen Zähler einführen j, der sich nicht linear und nicht sequentiell ändert. Ich würde dann bei jeder Iteration den aktuellen Wert von eingeben wollen j, myprogramaber der Wert von jkann sich zwischen dem Aufruf von myprogram -optionsund dem Ende der Datei ändern EOF.

Haben Sie Vorschläge?

Antwort1

Bei fast allen Programmen sollten sowohl echo $i | myprogram -optionsals auch myprogram -options <<<$ifunktionieren, indem das Programm $iüber die Standardeingabe gespeist wird.

<fooverwendet den Inhalt der Datei foomit dem Namen stdin.

<<foofoowird den Text zwischen diesem und einer Zeile, die ausschließlich aus besteht , als Standardeingabe verwenden . Dies ist einehier Dokument(Heredoc) EOFbedeutet, wie Gilles sagte, nicht wirklich das Ende der Datei, sondern ist nur ein allgemeiner Heredoc-Abgrenzungsparameter (in diesem Beispiel verwenden wir stattdessen „foo“).

<<<fooverwendet die Zeichenfolge "foo" als Standardeingabe. Sie können auch eine Variable angeben $foo, und die Shell verwendet ihren Inhalt als Standardeingabe, wie ich oben gezeigt habe. Dies nennt manhierstring, da es im Gegensatz zu einem ganzen Block, wie in einem Heredoc, einen kurzen String verwendet. Herestrings funktionieren in Bash, aber nicht in /bin/sh.

Antwort2

Die von dieser Website empfohlene Syntax heißthier Dokument. Die Eingabe in die Datei program beginnt unmittelbar unter der Zeile, die enthält <<EOF, und wird nicht durch das Ende des Skripts beendet, sondern durch eine Zeile, die genau den Text enthält EOF(achten Sie darauf, dass keine zusätzlichen Leerzeichen vorhanden sind). Übrigens können Sie jeden Endmarker verwenden, der kein Shell-Sonderzeichen enthält: EOFist kein Schlüsselwort, sondern lediglich Tradition.

#!/bin/bash
for i in {1..100}
do
   myprogram -options <<EOF
$i
EOF
   for j in {1..42}; do
     myprogram2 <<EOF
$i
$j
EOF
   done
done

Antwort3

Hier sind die Dokumente, wie sie oben von Kevin und Gilles erwähnt wurden, oder in vielen Fällen funktioniert auch eine einfache Weiterleitung.

Für kompliziertere Situationen sollten Sie sich Expect oder ähnliches ansehen (z. B. ist das CPAN-Modul Expect::Simple eine sehr einfach zu verwendende Perl-Implementierung). Ich persönlich bevorzuge das Perl-Modul (Expect selbst ist Tcl), aber es gibt Implementierungen für viele gängige Skriptsprachen. Es ist sogar möglich, einsehrprimitive Implementierung der Idee in sh oder bash mit while und read.

Die allgemeine Idee von Expect und ähnlichen Tools besteht darin, auf eine bestimmte Zeichenfolge oder ein bestimmtes Muster in der Ausgabe eines Programms zu warten und ihm dann die gewünschte Eingabe zuzuführen.

Ein häufiges Anwendungsbeispiel ist die Automatisierung der Anmeldung, indem die Zeichenfolge „ogin:“ „erwartet“ (d. h. darauf gewartet wird), der Anmeldename gesendet wird, dann die Zeichenfolge „word:“ erwartet wird und das Kennwort gesendet wird.

Eine letzte Möglichkeit, wenn Sie den Quellcode von myprogram haben, besteht darin, ihn einfach so zu ändern, dass er die gewünschte Eingabe als Befehlszeilenoption akzeptiert. Das ist zwar anfangs vielleicht etwas mehr Arbeit, aber viel weniger ärgerlich, als mit Expect herumzuspielen oder Daten in ein Programm einzuspeisen, das nicht für diese Verwendung konzipiert wurde.

... und vergessen Sie nicht, Ihren Patch an myprogram zurück an den Upstream zu senden :) Selbst wenn ihnen nicht gefällt, wie Sie es codiert haben, gefällt ihnen die Idee vielleicht so gut, dass sie die Funktion selbst hinzufügen. Upstream-Entwickler schätzen in der Regel Leute, die sich ins Zeug legen und etwas beitragen, anstatt Forderungen zu stellen oder sich zu beschweren.

verwandte Informationen