问题描述
我正在使用RVM,Ruby 1.9.2和Rails 3.0.7
从另一个终端进行的标准杀死进程也不起作用,但是杀死-9当然可以。
我发现了类似的问题CTRL+C to Webbrick server ignored,但尚不清楚该问题是否描述了相同的潜在问题。另外,该分辨率似乎不适用,因为我在Gemfile中未使用:git。
更新1 :(现在已经很旧了,请参阅下面的更新2,了解真正的消息)
我设法将问题缩小为一个 gems 。如果您提供以下测试脚本,您也可以看到该问题(假设您使用的是Ubuntu 11.04 …在10.04中没有问题)
rm -rf tmpkilltest
rvm 1.9.2
rvm --force gemset delete tmpkilltest
rvm gemset create tmpkilltest
rvm 1.9.2@tmpkilltest
gem install rails -v=3.0.7 --no-rdoc --no-ri
gem install sqlite3 -v=1.3.3 --no-rdoc --no-ri
rails new tmpkilltest
cd tmpkilltest
echo "gem 'barista', '1.0'" >> Gemfile
bundle
rails s
这个问题是由Rails与gem的交互引起的,这使我现在相信这个问题实际上与CTRL+C to Webbrick server ignored有关,尽管上面的测试案例表明,这个问题显然不是由:git应用于gem引起的。
更新2:
在更新1中,我提到我将其范围缩小为一个 gems 。当我经历那颗 gems 时,我最终找到了真正的罪魁祸首。 gem正在进行单个系统调用。我对测试脚本进行了非常小的修改,不再加载咖啡师gem,而是在application.rb的末尾附加一个系统调用。通过该系统调用,ctrl-c不起作用。删除系统调用,它确实起作用。
rm -rf tmpkilltest
rvm 1.9.2
rvm --force gemset delete tmpkilltest
rvm gemset create tmpkilltest
rvm 1.9.2@tmpkilltest
gem install rails -v=3.0.7 --no-rdoc --no-ri
gem install sqlite3 -v=1.3.3 --no-rdoc --no-ri
rails new tmpkilltest
cd tmpkilltest
bundle
echo "\`date\`" >> config/application.rb
rails s
这可以解释这个问题和CTRL+C to Webbrick server ignored之间看似相似的地方。我的直觉是,他们提到的gem也可以进行系统调用。
最佳方案
我宁愿发表评论,也不愿为此添加答案,但代表不足。
我遇到了同样的问题,发现在键入ctrl
–c
之后恢复(使用fg
),然后暂停(如上所述,使用ctrl
–z
)可以解决问题。
所以配方是:
-
ctrl
–c
(立即不执行任何操作) -
ctrl
–z
(暂停WEBrick,返回Shell) -
fg
(恢复WEBrick,立即使用SIGINT进行操作)lampadmin@lampadmin-DX4840:/var/www/rails/agences$ r s => Booting WEBrick => Rails 3.0.5 application starting in development on http://0.0.0.0:3000 => Call with -d to detach => Ctrl-C to shutdown server [2011-05-14 14:25:36] INFO WEBrick 1.3.1 [2011-05-14 14:25:36] INFO ruby 1.9.2 (2011-02-18) [x86_64-linux] [2011-05-14 14:25:36] INFO WEBrick::HTTPServer#start: pid=2585 port=3000
^ C^Z(<-ctrl-c,然后ctrl-z)
[1]+ Stopped rails s lampadmin@lampadmin-DX4840:/var/www/rails/agences$ fg rails s [2011-05-14 14:25:45] INFO going to shutdown ... [2011-05-14 14:25:45] INFO WEBrick::HTTPServer#start done. Exiting
次佳方案
我遇到类似的问题,一直在使用Ctrl
+ Z
暂停作业,然后使用kill -9 %1
杀死第一个暂停的作业。回旋处杀死它的方法,但是它起作用。
有关更多信息,请参见超级用户的此问题:https://superuser.com/questions/243460/what-to-do-when-ctrl-c-cant-kill-a-process
第三种方案
我相信^C
无法杀死WEBrick服务器,因为该服务器创建了一个新会话:
在webrick/server.rb
中:
class Daemon def Daemon.start exit!(0) if fork Process::setsid exit!(0) if fork Dir::chdir("/") File::umask(0) STDIN.reopen("/dev/null") STDOUT.reopen("/dev/null", "w") STDERR.reopen("/dev/null", "w") yield if block_given? end end
(rack/server.rb
中存在非常相似的代码,因此,如果要通过机架启动WEBrick,则可能要忽略-D
或--daemonize
命令行选项。)
从setsid(2)
的联机帮助页中:
setsid() creates a new session if the calling process is not a process group leader. The calling process is the leader of the new session, the process group leader of the new process group, and has no controlling tty.
没有控制tty意味着终端产生的信号(^Z
SIGTSTP
,^\
SIGKILL
,SIGTTIN
,SIGTTOU
等)即使已在该终端上启动也无法到达该过程。链接已切断。
第四种方案
好的,问题已为我解决。我最近将其作为Ubuntu标准更新的一部分进行了内核更新,从而解决了该问题。
另外,这里是对该问题的精彩讨论,它说明了根本原因是2.6.38(http://redmine.ruby-lang.org/issues/4777)中引入的内核回归。
回归已得到修补,看起来该修补程序最近已成为Ubuntu的更新程序,因此,如果您受到此问题的影响,则应应用最新更新。
第五种方案
在Mac OS X上,这也发生在我身上。
令人惊讶的是,Rack
或WEBrick
都没有设置自定义信号处理程序。我将其放在机架应用程序的call
方法中,它告诉我SIGINT的DEFAULT
处理程序是当前处理程序(返回字符串"DEFAULT"
):
p Signal.trap('INT', 'DEFAULT')
我怀疑在红 gems 的select
中发生了某种情况,正在捕获信号。
这是两种将其停止服务器的方法:
1)按ctrl-z暂停。然后kill -ABRT pid_or_job_id
。我不知道该如何退出”cleanly”。这很烦人,但您不必添加任何代码。
2a)如果您使用的是Rack,请在致电Rack::Handler::WEBrick.run
之前添加此权限:
Signal.trap('INT') {
Rack::Handler::WEBrick.shutdown
}
2b)如果您使用香草WEBrick
:
Signal.trap('INT') { server.shutdown }
其中server
是您的WEBrick
服务器对象。
如果您将经常使用SIGINT
,则这些功能很好。您可能还想为TERM
和HUP
添加处理程序。