Tcl Expect脚本-派生自分叉子进程的进程从不返回EOF

Tcl Expect脚本-派生自分叉子进程的进程从不返回EOF,tcl,fork,expect,spawn,Tcl,Fork,Expect,Spawn,我遇到了另一种奇怪的行为,我似乎找不到答案。当我用最简单的代码看到这个问题时,这些问题真的很令人困惑,这几乎是从探索Expect的书中直接出来的。我不确定我为什么会看到这些问题,而且似乎没有其他人有任何问题 再一次,我把它归结为一个超级简单的脚本。如果我在没有参数的情况下运行它,它不会将进程分给子进程并杀死父进程。如果我向它传递任何参数,它将使用fork创建一个子对象。当它作为父进程运行时,它会按预期正常工作。但是当它在子进程中运行时,“expect”命令似乎没有连接到任何东西,因为它没有从派生

我遇到了另一种奇怪的行为,我似乎找不到答案。当我用最简单的代码看到这个问题时,这些问题真的很令人困惑,这几乎是从探索Expect的书中直接出来的。我不确定我为什么会看到这些问题,而且似乎没有其他人有任何问题

再一次,我把它归结为一个超级简单的脚本。如果我在没有参数的情况下运行它,它不会将进程分给子进程并杀死父进程。如果我向它传递任何参数,它将使用fork创建一个子对象。当它作为父进程运行时,它会按预期正常工作。但是当它在子进程中运行时,“expect”命令似乎没有连接到任何东西,因为它没有从派生的进程接收任何输出。我只是对这里发生的事情了解不够,无法调试这个问题

简单(更新)脚本:

在没有任何分叉的情况下运行“cat”(正常前台进程):

在没有任何分叉的情况下运行“cat”(后台进程):

第二个快照(子活动,父活动):

第三个快照(子快照和活快照):

在这里,我觉得奇怪的是,生成的进程有一个新的、唯一的TTY pty/37,而子进程有一个TTY pty/35(与启动它的tcsh TTY匹配)。这与孩子仍然能够向stdout发送文本是一致的,而spawened进程似乎无法向任何地方发送任何内容。从Expect派生的进程是否需要唯一的pts/37 TTY?我记得我读过一篇文章,Expect创建了一个新的伪终端,用于与它派生的进程进行通信。但如果是这样的话,为什么Expect会失去与pty/37连接的派生进程的通信

我试图收集更多的线索和信息,但这里有些东西似乎仍然很可疑。这正是Expect的设计初衷,而其行为似乎与我所理解的并不一致。如果在安装程序上运行我的简单示例脚本,其他人是否也会看到同样的行为

提前感谢您的帮助或建议。

使用: expect\u用户[expect\u参数] 与expect类似,但它从stdin读取字符(即。 来自用户的击键)。默认情况下,在中执行读取 烹饪模式。因此,行必须以返回结束,以便 希望能见到他们。可通过stty进行更改(参见stty 命令)


而不是expect对我有效。

我不知道,但我怀疑
eof=
与此相关。谢谢Donal。我还认为stty的输出起初看起来可疑。我尝试了一个简单的实验,从stty得到了相同的结果。运行“stty&”报告了相同的信息。我知道,如果您在后台启动expect,它似乎在没有分叉的情况下正常工作。我还看到在流程树中发生了一些有趣的事情,我将添加到原始问题中,希望它提供进一步的线索。我不确定这是如何解决我所看到的问题的。expect_user用于捕获来自用户的输入,与派生子进程产生的进程缺乏通信无关。除非我错过了什么。。。
package require Expect


puts "Tcl version   : [info tclversion]"
puts "Expect version: [exp_version]"


# Any passed in argument will enable forking to child process
#    fork_cat : Forks and then spawns a process to simply cat a text to stdout
#    fork_wish: Forks and then spawns a process to start up wish which opens the
#               Tk window as well out the interactive prompt % from the interpreter.
if {$argc > 0} {

   while {1} {
      # If forking fails, retry every 10 seconds until it succeeds.
      if {[catch fork child_pid] == 0} {
         break
      }
      sleep 10
   }

   if {[lindex $argv 0] == "fork_wish"} {
      # Delay so process tree snapshot can be captured with both parent and child processes
      sleep 20
   }

   # Kills the parent process to return terminal control to shell
   if {$child_pid != 0} {
      puts "[pid] Parent process exiting..."
      exit
   }

   if {[lindex $argv 0] == "fork_wish"} {
      # Delay so process tree snapshot can be captured of only child process after parent exits
      sleep 20
   }

   # 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]
   }

}

sleep 1


# Show stty output in case it is relevant to debugging
puts ""
stty -a
puts ""

# Spawn process to cat a text file
switch -exact [lindex $argv 0] {
   "fork_cat" {
      set spawned_pid [spawn -noecho cat 123.txt]
   }
   "fork_wish" {
      set spawned_pid [spawn -noecho wish]
   }
   default {
      set spawned_pid [spawn -noecho cat 123.txt]
   }
}

while {1} {
   expect {
      eof {
         puts ""
         puts "[pid] Process received EOF from spawned process"
         break
      }
      timeout {
         puts ""
         puts "[pid] Process expect timed out for spawned process"
      }
   }
}


puts ""
puts "[pid] Process exiting..."
exit
:> temp_eof

Tcl version   : 8.4
Expect version: 5.43.0

speed 38400 baud; line = 0;
-brkint ixoff -imaxbel

123
123
123
123
123

15060 Process recieved EOF from spawned process

15060 Process exiting...
:> temp_eof &
[1] 15081

:> Tcl version   : 8.4
Expect version: 5.43.0

speed 38400 baud; line = 0;
eof = <undef>; susp = <undef>; rprnt = <undef>; werase = <undef>; lnext = <undef>; min = 1; time = 0;
-brkint inlcr ixoff -imaxbel
-icanon -iexten -echo -echok

123
123
123
123
123

15081 Process received EOF from spawned process

15081 Process exiting...

[1]  + Suspended (tty output)        temp_eof

[lc-bun-019: AB: ~/bin]
:> fg
temp_eof
:> temp_eof fork_cat

Tcl version   : 8.4
Expect version: 5.43.0
15121 Parent process exiting...

:>

speed 38400 baud; line = 0;
eof = <undef>; susp = <undef>; rprnt = <undef>; werase = <undef>; lnext = <undef>; min = 1; time = 0;
-brkint inlcr ixoff -imaxbel
-icanon -iexten -echo -echok


15123 Process expect timed out for spawned process

15123 Process expect timed out for spawned process

15123 Process expect timed out for spawned process

15123 Process expect timed out for spawned process

15123 Process expect timed out for spawned process

15123 Process expect timed out for spawned process

15123 Process expect timed out for spawned process


:> pkill temp_eof
:> temp_eof fork_wish

Tcl version   : 8.4
Expect version: 5.43.0
29172 Parent process exiting...

:>

speed 38400 baud; line = 0;
eof = <undef>; susp = <undef>; rprnt = <undef>; werase = <undef>; lnext = <undef>; min = 1; time = 0;
-brkint inlcr ixoff -imaxbel
-icanon -iexten -echo -echok


29174 Process expect timed out for spawned process

29174 Process expect timed out for spawned process

29174 Process expect timed out for spawned process

29174 Process expect timed out for spawned process

29174 Process expect timed out for spawned process

29174 Process expect timed out for spawned process

29174 Process expect timed out for spawned process


:> pkill temp_eof
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND

    1 24566 24564 20131 pts/30   20131 S     9276   0:00 konsole -T Main /dev/null
24566 24569 24569 24569 pts/35   29172 Ss    9276   0:00  \_ -bin/tcsh
24569 29172 29172 24569 pts/35   29172 Sl+   9276   0:00  |   \_ /usr/local/bin/tclsh temp_eof fork_wish
29172 29174 29172 24569 pts/35   29172 S+    9276   0:00  |       \_ /usr/local/bin/tclsh temp_eof fork_wish
24566 26530 26530 26530 pts/36   29175 Ss    9276   0:00  \_ -bin/tcsh
26530 29175 29175 26530 pts/36   29175 R+    9276   0:00      \_ ps axjf
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND

    1 24566 24564 20131 pts/30   20131 S     9276   0:00 konsole -T Main /dev/null
24566 24569 24569 24569 pts/35   24569 Ss+   9276   0:00  \_ -bin/tcsh
24566 26530 26530 26530 pts/36   29176 Ss    9276   0:00  \_ -bin/tcsh
26530 29176 29176 26530 pts/36   29176 R+    9276   0:00      \_ ps axjf
    1 29174 29172 24569 pts/35   24569 S     9276   0:00 /usr/local/bin/tclsh temp_eof fork_wish
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND

    1 24566 24564 20131 pts/30   20131 S     9276   0:00 konsole -T Main /dev/null
24566 24569 24569 24569 pts/35   24569 Ss+   9276   0:00  \_ -bin/tcsh
24566 26530 26530 26530 pts/36   29192 Ss    9276   0:00  \_ -bin/tcsh
26530 29192 29192 26530 pts/36   29192 R+    9276   0:00      \_ ps axjf
    1 29174 29172 24569 pts/35   24569 S     9276   0:00 /usr/local/bin/tclsh temp_eof fork_wish
29174 29178 29178 29178 pts/37   29178 Ssl+  9276   0:00  \_ /usr/bin/wish