我正在使用expect在我的服务器上启动应用程序:
!/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并在结束时获得以下输出:
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 0
,interact
,exp_continue
,disconnect
,sleep 10
,并期待{{1}但似乎没有任何工作。我也试过运行eof
,但这也不起作用。
当我手动运行bin / start-all.sh时,脚本会启动必要的进程然后退出。然而,期望这些过程似乎被杀死。我该如何解决这个问题?
答案 0 :(得分:7)
我遇到了同样的问题并想出了这个问题。
当expect
退出时,它会向生成的子流程发送SIGHUP
(挂断信号)。默认情况下,此SIGHUP
会导致生成的进程终止。
如果您希望基础流程不会死于SIGHUP
,那么您有两个简单的选择。两者都运作良好:
1)要求expect
使基础流程忽略SIGHUP
行中的spawn
,如下所示:
#!/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
这是一个正在运行的例子:
$ ./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;}
答案 1 :(得分:0)
我发现在Expect中程序运行奇怪的几乎所有情况下都有一件事就是在屏幕实例中生成一个shell并从那里运行程序。
spawn screen bash
send "bin/start-all.sh\r"
尝试这样做,看看它是否可以解决你过早的eof问题。