背景催生了Expect的过程

Luc*_*cas 11 unix shell tcl expect background-process

我正在使用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 }
}
Run Code Online (Sandbox Code Playgroud)

我可以在脚本运行的几秒钟内访问我的服务器上的应用程序,但是一旦它结束,应用程序就会变得不可用.

我在调试模式下运行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
Run Code Online (Sandbox Code Playgroud)

我已经尝试使用exit 0,interact,exp_continue,disconnect,sleep 10最后的模式下,以及期待eof,但似乎没有奏效.我也试过跑,expect start-all.exp &但这也不起作用.

当我手动运行bin/start-all.sh时,脚本启动必要的进程然后退出.然而,期望这些过程似乎被杀死.我该如何解决这个问题?

ari*_*elf 10

我遇到了同样的问题并想出了这个问题.

expect退出时,它发送一个SIGHUP(挂机信号)到生成的子进程.默认情况下,这SIGHUP会导致生成的进程终止.

如果你想让基础过程不死,SIGHUP你有两个简单的选择.两者都运作良好:

1)要求在这样的行expect中忽略底层进程:SIGHUPspawn

#!/usr/bin/expect -f
...
spawn -ignore HUP command args...
...
expect_background
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

这是一个运行的例子:

$ ./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
Run Code Online (Sandbox Code Playgroud)

正如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;}
Run Code Online (Sandbox Code Playgroud)