1

我已经进行了大量的搜索和试验,试图自己解决这个问题,但我找不到答案。

背景:

我正在使用 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 u 来帮助显示 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
4

1 回答 1

0

子进程作业完成后,您应该从程序中的某个位置退出子进程。我没有看到你在任何地方这样做。我只看到在父进程上调用了退出。

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
}
于 2017-07-19T15:46:09.193 回答