2013-07-29 18 views
9

Erwartet Ich verwende erwarten eine Anwendung auf meinem Server zu starten:Hintergrund erzeugten Prozess in

!/usr/bin/expect 

set timeout -1 

spawn "bin/start-all.sh" 
expect { 
    -re "Found MongoDB in" { send "y\r"; exp_continue } 
    -re "Found Hadoop in" { send "y\r"; exp_continue } 
    -re "Going to start Hadoop" { interact } 
} 

ich die Anwendung auf meinem Server in den wenigen Sekunden zugreifen kann, während das Skript ausgeführt wird, aber sobald Es endet die Anwendung wird nicht verfügbar.

Ich habe laufen im Debug-Modus erwarten und die folgende Ausgabe zum Ende erhalten:

expect: does "vendors area. Do you want to start it? [y/n] y\r\n" (spawn_id exp6) match regular expression "Found MongoDB in"? Gate "Found MongoDB in"? gate=no 
"Found Hadoop in "? Gate "Found Hadoop in "? gate=no 
"Going to start Hadoop"? Gate "Going to start Hadoop"? gate=no 
Going to start Hadoop... 

expect: does "vendors area. Do you want to start it? [y/n] y\r\nGoing to start Hadoop...\r\n" (spawn_id exp6) match regular expression "Found MongoDB in"? Gate "Found MongoDB in"? gate=no 
"Found Hadoop in "? Gate "Found Hadoop in "? gate=no 
"Going to start Hadoop"? Gate "Going to start Hadoop"? gate=yes re=yes 
expect: set expect_out(0,string) "Going to start Hadoop" 
expect: set expect_out(spawn_id) "exp6" 
expect: set expect_out(buffer) "vendors area. Do you want to start it? [y/n] y\r\nGoing to start Hadoop" 
tty_raw_noecho: was raw = 0 echo = 1 
interact: received eof from spawn_id exp6 
tty_set: raw = 0, echo = 1 
tty_set: raw = 5, echo = 0 

Ich habe versucht, mit exit 0, interact, exp_continue, disconnect, sleep 10 unter dem letzten Muster, sowie erwartet eof, aber nichts scheint zu funktionieren. Ich habe auch versucht, expect start-all.exp & zu laufen, aber das funktioniert auch nicht.

Wenn ich bin/start-all.sh manuell ausführen, startet das Skript die notwendigen Prozesse und wird dann beendet. Allerdings erwarten diese Prozesse, dass sie getötet werden. Wie würde ich dieses Problem beheben?

+0

Es gibt viele Details, aber es ist nicht klar, was genau Sie erreichen möchten. –

+1

Es ist ein langer Schuss, aber hast du am Ende "expect eof" probiert? –

+0

Ich fürchte, ich bin mit diesem start-all.sh-Skript nicht vertraut. Es ist möglich, dass es etwas seltsames macht, wenn es in Expect's PTY läuft, was zu einem vorzeitigen Abbruch führt. – user108471

Antwort

0

Eine Sache, die ich in fast allen Situationen gefunden habe, in denen Programme seltsam in Expect laufen, ist, eine Shell in einer Bildschirminstanz zu erzeugen und das Programm von dort aus auszuführen.

Versuchen Sie das und sehen Sie, ob es Ihr vorzeitiges eof Problem behebt.

+0

Mit dieser Lösung könnten Sie viele Bildschirmsitzungen ausführen, nachdem Sie das Expect-Skript mehrmals ausgeführt haben. – Bogdan

+0

@Bogdan Nicht unbedingt. Gemäß der ursprünglichen Frage wird das Script beim manuellen Ausführen am Ende des Skripts beendet, ohne die gestarteten untergeordneten Prozesse zu löschen. Wenn das Ausführen des gleichen Skripts in einer Screen-Sitzung wie das manuelle Ausführen des Skripts funktioniert, sollten Sie die Screen-Sitzung am Ende beenden können, ohne diese Prozesse ebenfalls zu beenden. Diese Bildschirmsitzungen müssen nicht lange laufen. – user108471

5

Ich hatte das gleiche Problem und dachte mir das aus.

Wenn expect beendet wird, wird ein SIGHUP (Auflegen-Signal) an den erzeugten Subprozess gesendet. Standardmäßig bewirkt diese SIGHUP Beendigung des erstellten Prozesses.

Wenn Sie wollen, dass der zugrunde liegende Prozess nicht von SIGHUP stirbt, haben Sie zwei einfache Möglichkeiten. Beide arbeiten gut:

1) Stellen Sie expect, um den zugrunde liegenden Prozess zu machen ignorieren SIGHUP in der spawn Zeile wie folgt aus:

#!/usr/bin/expect -f 
... 
spawn -ignore HUP command args... 
... 
expect_background 

2) Do it yourself - ignorieren SIGHUP in der zugrunde liegenden Prozess selbst:

Hier arbeitet Skript demonstriert Methode 2:

#!/usr/bin/expect -f 
# 
# start a process and background it after it reaches a certain stage 
# 
spawn perl -e "\$SIG{HUP} = 'IGNORE'; for (\$a='A';; \$a++) {print qq/value is \$a\\n/; sleep 1;}" 

set timeout 600 

# Detailed log so we can debug (uncomment to enable) 
# exp_internal -f /tmp/expect.log 0 

# wait till the subprocess gets to "G" 
expect -ex "value is G" 

send_user "\n>>> expect: got G\n" 

# when we get to G, background the process 
expect_background 

send_user ">>> spawned process backgrounding successful\n" 
exit 0 

Hier ist ein Lauf Beispiel:

$ ./expect-bg 
spawn perl -e $SIG{HUP} = 'IGNORE'; for ($a='A';; $a++) {print qq/value is $a\n/; sleep 1;} 
value is A 
value is B 
value is C 
value is D 
value is E 
value is F 
value is G 

>>> expect: got G 
>>> spawned process backgrounding successful 

Und wie erwartet in ps-Ausgabe ist der Perl-Prozess Hintergrund und lebendig.

USER  PID %CPU %MEM VSZ RSS TTY  STAT START TIME COMMAND 
hankm  6700 0.0 0.0 17696 2984 ?  Ss 18:49 0:00 perl -e $SIG{HUP} = 'IGNORE'; for ($a='A';; $a++) {print qq/value is $a\n/; sleep 1;} 
+0

Perfekt, vielen Dank für das Erwähnen! –