Warum funktioniert der Interaktionsbefehl von Expect nicht?

8

Ich versuche, GDB mit Erwartung zu automatisieren. Mein Skript startet gdb, führt eine Initialisierung durch und übergibt das Steuerelement an den Benutzer. Der interactBefehl von Expect scheint das perfekte Werkzeug für diesen Job zu sein.

Betrachten Sie nun:

$ echo "spawn gdb
    expect \"(gdb) \"
    send \"help\r\"
    expect \"(gdb) \"
    interact" | expect -

Auf meinen Computern erzeugt dieses Scriptlet gdb und gibt erwartungsgemäß den Hilfebefehl aus. Aber dann verlässt es sofort das Skript und bringt mich zur Bash-Eingabeaufforderung zurück. Ich würde erwarten, dass der Benutzer innerhalb von gdb bleibt und Befehle ausgeben kann.

Irgendeine Idee, was mir hier fehlt?

Nicolas Bonnefon
quelle
Laufen Sie unter Windows?
Glenn Jackman

Antworten:

12

interacterhält seine Eingabe von der expectsStandardeingabe, die die Pipe ist, die echojetzt geschlossen wird.

Sie können es stattdessen schreiben (ksh / zsh / bash-Syntax):

expect <(echo "spawn gdb
  expect \"(gdb) \"
  send \"help\r\"
  expect \"(gdb) \"
  interact" )

Das wird immer noch über eine Pipe gespeist, aber dieses Mal wird die Pipe als Pfadargument angegeben, expectdamit erwartet wird, dass der Standard nicht beeinflusst wird.

In diesem Fall wäre es jedoch naheliegend, Folgendes zu schreiben:

expect -c '
  spawn gdb
  expect "(gdb)"
  send "help\r"
  expect "(gdb) "
  interact'

expectlike shund die meisten Shells erlauben das Übergeben von Inline-Skripten mit -c.

Wenn Sie die Ausgabe eines Befehls noch übergeben müssen (wie echoin Ihrem Fall), können Sie dies auch tun -cmit:

expect -c "$(echo...)"

Dies bedeutet jedoch, dass im Gegensatz zu den Pipe-Ansätzen expecterst gestartet wird, wenn dieser Befehl beendet ist.

Übrigens, hier könnten Sie .gdbinit stattdessen eine Datei oder eine -ixOption verwenden gdb, die Sie nicht wirklich brauchen expect.

Stéphane Chazelas
quelle
Danke, es macht wirklich Sinn. Könnten Sie bitte die <() -Konstruktion näher erläutern (oder auf die Dokumentation verweisen)? Ich weiß es nicht und es ist schwer zu googeln!
Nicolas Bonnefon
Ja, ich weiß auch über -ix Bescheid, aber mein echtes Skript ist viel komplexer und in diesem Fall brauche ich die Flexibilität, die ich erwarten kann. Guter Vorschlag.
Nicolas Bonnefon
1
@NicolasBonnefon. Das nennt man Prozesssubstitution , eine ksh-Funktion. Viele Fragen und Antworten dazu auf U & L
Stéphane Chazelas
@NicolasBonnefon @ StéphaneChazelas Ich konnte vermeiden, den Anführungszeichen zu entkommen, indem ich das Konstrukt verwendeteexpect <(cat <<- 'EOF' ... EOF )
Andreas
warum so verwickelt? Warum nicht einfach ein `#! / usr / bin / expected -f`` Skript schreiben?
Cas