Фон породил процесс в ожидании

Я использую функцию ожидаемого запуска приложения на моем сервере:

#!/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 0, interact, exp_continue, disconnect, sleep 10 по последнему шаблону, а также ожидал eof, но, похоже, ничего не работает. Я также пытался запустить expect start-all.exp &, но это тоже не работает.

Когда я запускаю bin/start-all.sh вручную, скрипт запускает необходимые процессы и затем завершает работу. Однако, как ожидается, эти процессы, кажется, убивают. Как бы я исправить эту проблему?

Ответ 1

У меня была та же проблема, и я понял это.

Когда expect завершает работу, он отправляет SIGHUP (сигнал зависания) на порожденный подпроцесс. По умолчанию этот SIGHUP вызывает завершение порожденного процесса.

Если вы хотите, чтобы основной процесс не умирал от SIGHUP, у вас есть два простых варианта. Оба работают хорошо:

1) Попросите expect заставить основной процесс игнорировать SIGHUP в строке spawn следующим образом:

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

2) Сделайте это самостоятельно - игнорируйте SIGHUP в самом базовом процессе:

Здесь рабочий script демонстрирует метод 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;}

Ответ 2

Одна вещь, с которой я столкнулся, работает практически во всех ситуациях, когда программы запущены странно в Expect - это порождать оболочку в экземпляре экрана и запускать программу оттуда.

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

Попробуйте сделать это и посмотрите, разрешит ли он вашу проблему преждевременной эмиссии.