我已经做了大量的搜索和试验,试图自己解决这个问题,但我还没有找到答案。
背景:
我正在使用Tcl版本8.4和Expect软件包扩展版本5.45编写脚本。我正在学习期待并发生在“背景处理”一章(第17章,探索期待)中。在页374-375中,它描述了“fork”命令。事实证明,这提供了我试图实现的功能。我需要运行脚本的第一部分,其中可能需要也可能不需要用户输入。从那时起,我希望终端将控制权返回给shell(就像脚本进程已被后台处理一样),同时脚本继续启动另一个工具并在退出之前等待它退出。然后,一旦完成,脚本过程就会正常死亡。
问题:
使用expect的fork命令时,一切似乎都在乍一看。我得到了父进程和子进程。父进程按指示退出,终端返回到shell控件。子进程继续启动它本应该使用的工具。问题是一旦该工具退出,子进程也应退出,但事实并非如此。该过程保持“S”或睡眠状态。仅供参考,我最初使用期望命令“断开”给孩子,但我意识到我实际上并不希望孩子完全断开连接。在我的实验中,断开连接似乎对退出后儿童过程是否仍然没有任何影响。
实验:
我试着把它归结为绝对的基础知识。所以这不是我的脚本,而是一个表现出相同行为的简化测试用例。我不得不遗漏一些东西。这不是正常的行为。我需要帮助弄清楚我做错了什么导致了这种行为。
简化的脚本:
puts "Tcl version : [info tclversion]"
puts "Expect version: [exp_version]"
while {1} {
# If forking fails, retry every 10 seconds until it succeeds.
if {[catch fork child_pid] == 0} {
break
}
sleep 10
}
sleep 10
# Kills the parent process to return terminal control to shell
if {$child_pid != 0} {
puts "[pid] Parent process exiting..."
exit
}
# Redefine exit procedure for child so it kills the process for sure on exit
# I have no idea why exit doesn't work for a child process, but this seems to ensure it goes away on exit.
#exit -onexit {
# puts "[pid] Killing PID..."
# exec kill [pid]
#}
puts "[pid] Child process sleeping for 10 seconds..."
sleep 10
puts "[pid] Child process waking up and exiting..."
exit
运行输出:
:> expect temp_fork
Tcl version : 8.5
Expect version: 5.45
31483 Child process sleeping for 10 seconds...
31472 Parent process exiting...
:> 31483 Child process waking up and exiting...
在另一个shell中,我运行了ps来帮助显示3点进程的进展情况。首先是在10秒睡眠期间,父母和孩子的过程都是活着的。第二个是在父进程退出之后,但是子进程正在休眠10秒。第三个是在孩子进程被假定退出之后,但由于某种原因,这个过程似乎还活着并且正在睡觉。
第一
:> ps u | grep expect
user 31472 0.2 0.0 6196 2524 pts/2 Sl+ 19:33 0:00 /tools/oss/packages/x86_64-rhel5/expect/default/bin/expect temp_fork
user 31483 0.0 0.0 6196 1456 pts/2 S+ 19:33 0:00 /tools/oss/packages/x86_64-rhel5/expect/default/bin/expect temp_fork
第二
:> ps u | grep expect
user 31483 0.0 0.0 6196 1576 pts/2 S 19:33 0:00 /tools/oss/packages/x86_64-rhel5/expect/default/bin/expect temp_fork
第三
:> ps u | grep expect
user 31483 0.0 0.0 6196 1700 pts/2 S 19:33 0:00 /tools/oss/packages/x86_64-rhel5/expect/default/bin/expect temp_fork
答案 0 :(得分:0)
在子进程作业完成后,您应该从程序中的某个位置退出子进程。我不认为你在任何地方都这样做。我只是看到父进程调用了exit。
while {1} {
# If forking fails, retry every 10 seconds until it succeeds.
if {[catch fork child_pid] == 0} {
# do your job with child process
exit
}
sleep 10
}