3 Stimmen

Verwendung von Expect mit Perl und Pipe in eine Datei

Ich bin ziemlich neu in Perl und haben die interwebs für die Dokumentation für das, was ich versuche, zu tun gesucht. Ich habe kein Glück.

Ich habe ein Programm, das Informationen auf stdout mit Aufforderungen ausgibt. Ich muss ein Perl-Skript erstellen, um diese Informationen in eine Datei zu leiten.

Ich dachte, ich könnte Expect verwenden, aber es scheint ein Problem mit der Pipe nach der ersten Eingabeaufforderung zu geben.

Hier ist der Teil meines Codes:

# Run program and compare the output to the BASE file
$cmd = "./program arg1 arg2 arg3 arg4 > $outfile";

my $exp = new Expect;
$exp->spawn($cmd);
BAIL_OUT("couldn't create expect object") if (! defined $exp);

$exp->expect(2);
$exp->send("\n");

In diesem Fall gibt es nur eine einzige Aufforderung an den Benutzer, "Enter" zu drücken. Dieses Programm ist klein und sehr schnell - 2 Sekunden reichen aus, um die erste Eingabeaufforderung zu erreichen.

Die Ausgabedatei enthält nur die erste Hälfte der Informationen.

Hat jemand einen Vorschlag, wie ich die zweite Hälfte auch noch bekommen kann?

UPDATE: Ich habe mit Hilfe eines einfachen Skripts überprüft, dass dies mit Expect funktioniert:

spawn ./program arg1 arg2 arg3 arg4
expect "<Return>"
send "\r"
interact

Dabei ist "< Return >" ein ausführlicher Ausdruck, nach dem das Perl-Skript suchen könnte.

Hinweis: Ich habe versucht, mein Perl-Skript so zu schreiben, dass es "< Return >" erwartet... es macht keinen Unterschied.

d.h.

$exp->expect(2, '-re', "<Return>")

Haben Sie eine Idee?

UPDATE2:

Hazaah! Ich habe eine Lösung für mein Problem gefunden... ganz zufällig.

Also, ich hatte einen Tippfehler in einem Testcode, den ich gemacht habe...

$exp->expect(2);
$exp->send("\r");
$exp->expect(2);

Man beachte das abschließende expect(2)... das habe ich versehentlich drin gelassen, und es hat funktioniert!

Ich versuche also zu verstehen, was hier passiert. Unix expect scheint nicht auf diese Weise zu funktionieren! Es scheint, dass das in Perl implementierte Expect alles "erwartet"... nicht nur Aufforderungen?

Ich erwarte also weitere 2 Sekunden, um stdout zu sammeln, und ich kann alles abrufen.

Wenn jemand genauere Informationen darüber geben kann, was hier vor sich geht, würde ich gerne verstehen, was vor sich geht.

4voto

evil otto Punkte 10038

Versuchen Sie zu senden \r 代わりに \n - Sie versuchen, einen Wagenrücklauf zu emulieren, nicht einen Zeilenumbruch, und die tty-Einstellungen übersetzen sie möglicherweise nicht.

ALSO:

Ein Vorschlag aus dem FAQ-Bereich der Expect-Dokumente, der angesichts Ihrer zufälligen Lösung wahrscheinlich ist:

Mein Skript schlägt von Zeit zu Zeit ohne ersichtlichen Grund fehl. Es Es scheint, dass ich manchmal die Ausgabe des gespawnten Programms verliere.

Sie könnten Ausgang sein genug Zeit zum Beenden zu geben. Versuchen Sie $exp->soft_close() hinzuzufügen, um das Programm zu beenden, oder führen Sie ein expect() für 'eof' durch.

Alternativ dazu können Sie auch eine Es könnte sein, dass die pty-Erstellung auf Ihrem System einfach langsam ist (aber das ist eher unwahrscheinlich, wenn Sie das neueste IO-Tty verwenden).

Der Standard unix/tcl expect beendet sich nicht im interaktiven Modus, was Ihrem Programm genügend Zeit geben könnte, die Ausführung zu beenden.

1voto

friedo Punkte 64178

Es ist schon eine Weile her, dass ich Expect benutzt habe, aber ich bin mir ziemlich sicher, dass Sie Expect etwas zur Verfügung stellen müssen, damit es die Eingabeaufforderung abgleichen kann:

$exp->expect( 2, 'Press enter' );

zum Beispiel.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X