下面的ruby代码显示一个问题,即在其子进程被暂停后恢复的父进程(SIGTSTP)在输入字符之后才会实际接收输入。
以下是使用以下代码重现的步骤:
repl.rb
,除非您输入“irb”,否则将回显您打印的内容。以下是repl.rb
的来源:
Signal.trap("SIGTSTP", "IGNORE")
pids = []
stty_save = `stty -g`
loop do
print "#{$0}> "
input = STDIN.gets.chomp
if input == "exit"
exit
else
command = nil
if input == "irb"
command = "irb"
elsif input == "fg" && pids.last
Process.kill "SIGCONT", pids.last
else
puts input
next
end
if command
pid = fork do
Signal.trap("SIGTSTP", "DEFAULT")
exec command
end
pids << pid
end
pid, status = Process.waitpid2 pids.last, Process::WUNTRACED if pids.last
if status.stopsig == 18 # stopped
system "stty", stty_save
puts "Stopped"
else
pids.pop
end
end
end
这是我得到的:
/tmp ➜ ruby repl.rb
repl.rb> foo
foo
repl.rb> irb
>> Stopped
repl.rb> foo
oo
repl.rb> exit
f/tmp ➜
这就是我的预期:
/tmp ➜ ruby repl.rb
repl.rb> foo
foo
repl.rb> irb
>> Stopped
repl.rb> foo
foo
repl.rb> exit
/tmp ➜
这适用于Linux(或至少Ubuntu 14.04.1)。我的主机出现问题的是运行Yosemite的OS X.
在Linux上,父进程接收信号编号20而不是18(如在OS X上)。