2013-07-29 45 views
9

我用期待我的服務器上啓動應用程序:背景衍生的過程中期待

!/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 } 
} 

我可以在腳本運行時我的服務器上訪問在幾秒鐘內的應用,但只要它結束應用程序變得不可用。

我已經運行預計在調試模式,得到下面的輸出接近尾聲:

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 

我已經嘗試使用exit 0interactexp_continuedisconnectsleep 10最後的模式下,以及期待eof,但似乎沒有任何工作。我也嘗試過運行expect start-all.exp &,但那也行不通。

當我手動運行bin/start-all.sh時,腳本啓動必要的過程,然後退出。但是,預計這些進程似乎會被殺死。我將如何解決這個問題?

+0

有很多的細節,但目前尚不清楚你想要實現什麼。 –

+1

這是一個很長的鏡頭,但你有沒有在最後嘗試'期待eof'? –

+0

恐怕我不熟悉這個start-all.sh腳本。在Expect的PTY中運行時,它可能會做一些奇怪的事情,導致它過早終止。 – user108471

回答

0

我發現在幾乎所有情況下,程序在Expect中運行奇怪的一件事是在屏幕實例中產生一個shell並從那裏運行程序。

spawn screen bash 
send "bin/start-all.sh\r" 

試着這樣做,看看它是否能解決您的早熟問題。

+0

使用此解決方案,您可能會多次執行expect腳本之後運行大量屏幕會話。 – Bogdan

+0

@Bogdan不一定。根據原始問題,當手動運行腳本時,它會在腳本結束時愉快退出而不會終止已啓動的子進程。如果在屏幕會話中運行相同的腳本就像手動運行腳本一樣,那麼最終應該能夠終止屏幕會話而不殺死這些進程。那些屏幕會話不需要長時間運行。 – user108471

5

我有同樣的問題,並想通了。

expect退出時,它發送SIGHUP(掛斷信號)到衍生的子過程。默認情況下,此SIGHUP導致產生的進程終止。

如果您希望底層進程不會從SIGHUP死掉,您有兩個簡單的選項。這兩個工作做好:

1)請expect,使底層程序忽略SIGHUPspawn一行:

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

2)做自己 - 在底層過程本身忽略SIGHUP

這裏的工作腳本演示方法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 

這裏有一個跑步ning示例:

$ ./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 

正如ps輸出中所預期的那樣,perl進程是後臺運行並存活的。

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

完美,謝謝你提到這個! –